Browse Source

Merge NRefactory 5.2.0-261-g7a948e7 to ILSpy.

pull/384/head
Daniel Grunwald 13 years ago
parent
commit
214c1f730d
  1. 8
      Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs
  2. 38
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  3. 4
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  4. 10
      ICSharpCode.Decompiler/Ast/Transforms/CombineQueryExpressions.cs
  5. 2
      ICSharpCode.Decompiler/Ast/Transforms/ExpressionTreeConverter.cs
  6. 2
      ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs
  7. 2
      ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs
  8. 2
      ICSharpCode.Decompiler/Tests/IL/ILTests.cs
  9. 2
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  10. 6
      ILSpy/Languages/CSharpLanguage.cs
  11. 6
      ILSpy/Properties/app.config.template
  12. 2
      ILSpy/SearchPane.cs
  13. 2
      ILSpy/VB/ILSpyEnvironmentProvider.cs
  14. 4
      ILSpy/VB/VBLanguage.cs
  15. 3
      NRefactory/.gitignore
  16. 3
      NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore
  17. 22
      NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
  18. 2
      NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs
  19. 3
      NRefactory/ICSharpCode.NRefactory.CSharp/.gitignore
  20. 1
      NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs
  21. 4
      NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs
  22. 43
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs
  23. 16
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs
  24. 6
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs
  25. 50
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs
  26. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs
  27. 8
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs
  28. 75
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs
  29. 9
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IdentifierExpression.cs
  30. 12
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs
  31. 10
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs
  32. 10
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedExpression.cs
  33. 11
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PointerReferenceExpression.cs
  34. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs
  35. 6
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs
  36. 6
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs
  37. 4
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs
  38. 1054
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs
  39. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs
  40. 4
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs
  41. 34
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs
  42. 81
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs
  43. 13
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs
  44. 1201
      NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs
  45. 134
      NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs
  46. 1095
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
  47. 389
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs
  48. 184
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs
  49. 120
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs
  50. 213
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs
  51. 7
      NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs
  52. 387
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
  53. 81
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs
  54. 132
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs
  55. 6
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs
  56. 14
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs
  57. 10
      NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/TextEditorOptions.cs
  58. 159
      NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
  59. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs
  60. 17
      NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
  61. 141
      NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs
  62. 471
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
  63. 151
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs
  64. 103
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/SeekableStreamReader.cs
  65. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
  66. 73
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
  67. 4
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
  68. 80
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
  69. 16
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
  70. 7
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs
  71. 16
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
  72. 10
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
  73. 45
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
  74. 40
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
  75. 52
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
  76. 16
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
  77. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
  78. 25
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
  79. 3
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs
  80. 9492
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
  81. 230
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay
  82. 266
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs
  83. 11
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs
  84. 5
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs
  85. 14
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs
  86. 73
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs
  87. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs
  88. 239
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs
  89. 11
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs
  90. 72
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs
  91. 5
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs
  92. 84
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs
  93. 49
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs
  94. 4
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs
  95. 50
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs
  96. 7
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs
  97. 58
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs
  98. 2
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs
  99. 161
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs
  100. 10
      NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs
  101. Some files were not shown because too many files have changed in this diff Show More

8
Debugger/Debugger.Core/NRefactory/Visitors/ExpressionEvaluator.cs

@ -73,14 +73,12 @@ namespace ICSharpCode.NRefactory.Visitors
switch (language) { switch (language) {
case SupportedLanguage.CSharp: case SupportedLanguage.CSharp:
var parser = new CSharpParser(); var parser = new CSharpParser();
using (var textReader = new StringReader(code)) { AstNode astRoot = parser.ParseExpression(code);
AstNode astRoot = parser.ParseExpression(textReader);
if (parser.HasErrors) { if (parser.HasErrors) {
throw new GetValueException("Parser errors"); throw new GetValueException("Parser errors");
} }
return astRoot; return astRoot;
}
default: default:
throw new ArgumentException("Unsuported language"); throw new ArgumentException("Unsuported language");
@ -125,14 +123,12 @@ namespace ICSharpCode.NRefactory.Visitors
switch (language) { switch (language) {
case SupportedLanguage.CSharp: case SupportedLanguage.CSharp:
var parser = new CSharpParser(); var parser = new CSharpParser();
using (var textReader = new StringReader(code)) { AstNode astRoot = parser.ParseExpression(code);
AstNode astRoot = parser.ParseExpression(textReader);
if (parser.HasErrors) { if (parser.HasErrors) {
throw new GetValueException("Parser errors"); throw new GetValueException("Parser errors");
} }
return astRoot as Expression; return astRoot as Expression;
}
default: default:
throw new ArgumentException("Unsuported language"); throw new ArgumentException("Unsuported language");
} }

38
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.Ast
public class AstBuilder public class AstBuilder
{ {
DecompilerContext context; DecompilerContext context;
CompilationUnit astCompileUnit = new CompilationUnit(); SyntaxTree syntaxTree = new SyntaxTree();
Dictionary<string, NamespaceDeclaration> astNamespaces = new Dictionary<string, NamespaceDeclaration>(); Dictionary<string, NamespaceDeclaration> astNamespaces = new Dictionary<string, NamespaceDeclaration>();
bool transformationsHaveRun; bool transformationsHaveRun;
@ -139,15 +139,15 @@ namespace ICSharpCode.Decompiler.Ast
public void RunTransformations(Predicate<IAstTransform> transformAbortCondition) public void RunTransformations(Predicate<IAstTransform> transformAbortCondition)
{ {
TransformationPipeline.RunTransformationsUntil(astCompileUnit, transformAbortCondition, context); TransformationPipeline.RunTransformationsUntil(syntaxTree, transformAbortCondition, context);
transformationsHaveRun = true; transformationsHaveRun = true;
} }
/// <summary> /// <summary>
/// Gets the abstract source tree. /// Gets the abstract source tree.
/// </summary> /// </summary>
public CompilationUnit CompilationUnit { public SyntaxTree SyntaxTree {
get { return astCompileUnit; } get { return syntaxTree; }
} }
/// <summary> /// <summary>
@ -159,16 +159,16 @@ namespace ICSharpCode.Decompiler.Ast
if (!transformationsHaveRun) if (!transformationsHaveRun)
RunTransformations(); RunTransformations();
astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
var outputFormatter = new TextOutputFormatter(output) { FoldBraces = context.Settings.FoldBraces }; var outputFormatter = new TextOutputFormatter(output) { FoldBraces = context.Settings.FoldBraces };
var formattingPolicy = context.Settings.CSharpFormattingOptions; var formattingPolicy = context.Settings.CSharpFormattingOptions;
astCompileUnit.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy)); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
} }
public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false) public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{ {
if (assemblyDefinition.Name.Version != null) { if (assemblyDefinition.Name.Version != null) {
astCompileUnit.AddChild( syntaxTree.AddChild(
new AttributeSection { new AttributeSection {
AttributeTarget = "assembly", AttributeTarget = "assembly",
Attributes = { Attributes = {
@ -185,10 +185,10 @@ namespace ICSharpCode.Decompiler.Ast
}, EntityDeclaration.AttributeRole); }, EntityDeclaration.AttributeRole);
} }
ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly"); ConvertCustomAttributes(syntaxTree, assemblyDefinition, "assembly");
ConvertSecurityAttributes(astCompileUnit, assemblyDefinition, "assembly"); ConvertSecurityAttributes(syntaxTree, assemblyDefinition, "assembly");
ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module"); ConvertCustomAttributes(syntaxTree, assemblyDefinition.MainModule, "module");
AddTypeForwarderAttributes(astCompileUnit, assemblyDefinition.MainModule, "assembly"); AddTypeForwarderAttributes(syntaxTree, assemblyDefinition.MainModule, "assembly");
if (!onlyAssemblyLevel) { if (!onlyAssemblyLevel) {
foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) {
@ -203,7 +203,7 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
void AddTypeForwarderAttributes(CompilationUnit astCompileUnit, ModuleDefinition module, string target) void AddTypeForwarderAttributes(SyntaxTree astCompileUnit, ModuleDefinition module, string target)
{ {
if (!module.HasExportedTypes) if (!module.HasExportedTypes)
return; return;
@ -237,7 +237,7 @@ namespace ICSharpCode.Decompiler.Ast
} else { } else {
// Create the namespace // Create the namespace
NamespaceDeclaration astNamespace = new NamespaceDeclaration { Name = name }; NamespaceDeclaration astNamespace = new NamespaceDeclaration { Name = name };
astCompileUnit.AddChild(astNamespace, CompilationUnit.MemberRole); syntaxTree.Members.Add(astNamespace);
astNamespaces[name] = astNamespace; astNamespaces[name] = astNamespace;
return astNamespace; return astNamespace;
} }
@ -248,31 +248,31 @@ namespace ICSharpCode.Decompiler.Ast
var astType = CreateType(typeDef); var astType = CreateType(typeDef);
NamespaceDeclaration astNS = GetCodeNamespace(typeDef.Namespace); NamespaceDeclaration astNS = GetCodeNamespace(typeDef.Namespace);
if (astNS != null) { if (astNS != null) {
astNS.AddChild(astType, NamespaceDeclaration.MemberRole); astNS.Members.Add(astType);
} else { } else {
astCompileUnit.AddChild(astType, CompilationUnit.MemberRole); syntaxTree.Members.Add(astType);
} }
} }
public void AddMethod(MethodDefinition method) public void AddMethod(MethodDefinition method)
{ {
AstNode node = method.IsConstructor ? (AstNode)CreateConstructor(method) : CreateMethod(method); AstNode node = method.IsConstructor ? (AstNode)CreateConstructor(method) : CreateMethod(method);
astCompileUnit.AddChild(node, CompilationUnit.MemberRole); syntaxTree.Members.Add(node);
} }
public void AddProperty(PropertyDefinition property) public void AddProperty(PropertyDefinition property)
{ {
astCompileUnit.AddChild(CreateProperty(property), CompilationUnit.MemberRole); syntaxTree.Members.Add(CreateProperty(property));
} }
public void AddField(FieldDefinition field) public void AddField(FieldDefinition field)
{ {
astCompileUnit.AddChild(CreateField(field), CompilationUnit.MemberRole); syntaxTree.Members.Add(CreateField(field));
} }
public void AddEvent(EventDefinition ev) public void AddEvent(EventDefinition ev)
{ {
astCompileUnit.AddChild(CreateEvent(ev), CompilationUnit.MemberRole); syntaxTree.Members.Add(CreateEvent(ev));
} }
/// <summary> /// <summary>

4
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -755,7 +755,7 @@ namespace ICSharpCode.Decompiler.Ast
for (int i = 0; i < args.Count; i++) { for (int i = 0; i < args.Count; i++) {
atce.Initializers.Add( atce.Initializers.Add(
new NamedExpression { new NamedExpression {
Identifier = ctor.Parameters[i].Name, Name = ctor.Parameters[i].Name,
Expression = args[i] Expression = args[i]
}); });
} }
@ -805,7 +805,7 @@ namespace ICSharpCode.Decompiler.Ast
MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single(); MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single();
initializer.Elements.Add( initializer.Elements.Add(
new NamedExpression { new NamedExpression {
Identifier = mre.MemberName, Name = mre.MemberName,
Expression = m.Get<Expression>("right").Single().Detach() Expression = m.Get<Expression>("right").Single().Detach()
}.CopyAnnotationsFrom(mre)); }.CopyAnnotationsFrom(mre));
} else { } else {

10
ICSharpCode.Decompiler/Ast/Transforms/CombineQueryExpressions.cs

@ -82,11 +82,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
new AnonymousTypeCreateExpression { new AnonymousTypeCreateExpression {
Initializers = { Initializers = {
new NamedExpression { new NamedExpression {
Identifier = Pattern.AnyString, Name = Pattern.AnyString,
Expression = new IdentifierExpression(Pattern.AnyString) Expression = new IdentifierExpression(Pattern.AnyString)
}.WithName("nae1"), }.WithName("nae1"),
new NamedExpression { new NamedExpression {
Identifier = Pattern.AnyString, Name = Pattern.AnyString,
Expression = new AnyNode("nae2Expr") Expression = new AnyNode("nae2Expr")
}.WithName("nae2") }.WithName("nae2")
} }
@ -114,11 +114,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last();
NamedExpression nae1 = match.Get<NamedExpression>("nae1").SingleOrDefault(); NamedExpression nae1 = match.Get<NamedExpression>("nae1").SingleOrDefault();
NamedExpression nae2 = match.Get<NamedExpression>("nae2").SingleOrDefault(); NamedExpression nae2 = match.Get<NamedExpression>("nae2").SingleOrDefault();
if (nae1 != null && nae1.Identifier != ((IdentifierExpression)nae1.Expression).Identifier) if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier)
return false; return false;
Expression nae2Expr = match.Get<Expression>("nae2Expr").Single(); Expression nae2Expr = match.Get<Expression>("nae2Expr").Single();
IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression;
if (nae2IdentExpr != null && (nae2 == null || nae2.Identifier == nae2IdentExpr.Identifier)) { if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) {
// from * in (from x in ... select new { x = x, y = y }) ... // from * in (from x in ... select new { x = x, y = y }) ...
// => // =>
// from x in ... ... // from x in ... ...
@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
} }
string ident; string ident;
if (nae2 != null) if (nae2 != null)
ident = nae2.Identifier; ident = nae2.Name;
else if (nae2Expr is IdentifierExpression) else if (nae2Expr is IdentifierExpression)
ident = ((IdentifierExpression)nae2Expr).Identifier; ident = ((IdentifierExpression)nae2Expr).Identifier;
else if (nae2Expr is MemberReferenceExpression) else if (nae2Expr is MemberReferenceExpression)

2
ICSharpCode.Decompiler/Ast/Transforms/ExpressionTreeConverter.cs

@ -567,7 +567,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
for (int i = 0; i < resolvedCtor.Parameters.Count; i++) { for (int i = 0; i < resolvedCtor.Parameters.Count; i++) {
atce.Initializers.Add( atce.Initializers.Add(
new NamedExpression { new NamedExpression {
Identifier = resolvedCtor.Parameters[i].Name, Name = resolvedCtor.Parameters[i].Name,
Expression = arguments[i].Detach() Expression = arguments[i].Detach()
}); });
} }

2
ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
for (int i = 1; i < parts.Length; i++) { for (int i = 1; i < parts.Length; i++) {
nsType = new MemberType { Target = nsType, MemberName = parts[i] }; nsType = new MemberType { Target = nsType, MemberName = parts[i] };
} }
compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, CompilationUnit.MemberRole); compilationUnit.InsertChildAfter(null, new UsingDeclaration { Import = nsType }, SyntaxTree.MemberRole);
} }
if (!context.Settings.FullyQualifyAmbiguousTypeNames) if (!context.Settings.FullyQualifyAmbiguousTypeNames)

2
ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.Tests
AssemblyDefinition assembly = Compile(code); AssemblyDefinition assembly = Compile(code);
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings }); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings });
decompiler.AddAssembly(assembly); decompiler.AddAssembly(assembly);
new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
StringWriter output = new StringWriter(); StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output)); decompiler.GenerateCode(new PlainTextOutput(output));
return output.ToString(); return output.ToString();

2
ICSharpCode.Decompiler/Tests/IL/ILTests.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler.Tests
var assembly = AssemblyDefinition.ReadAssembly(Path.Combine(path, compiledFile)); var assembly = AssemblyDefinition.ReadAssembly(Path.Combine(path, compiledFile));
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly); decompiler.AddAssembly(assembly);
new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
StringWriter output = new StringWriter(); StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output)); decompiler.GenerateCode(new PlainTextOutput(output));
CodeAssert.AreEqual(expectedOutput, output.ToString()); CodeAssert.AreEqual(expectedOutput, output.ToString());

2
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.Tests
AssemblyDefinition assembly = Compile(code, optimize, useDebug); AssemblyDefinition assembly = Compile(code, optimize, useDebug);
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly); decompiler.AddAssembly(assembly);
new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
StringWriter output = new StringWriter(); StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output)); decompiler.GenerateCode(new PlainTextOutput(output));
CodeAssert.AreEqual(code, output.ToString()); CodeAssert.AreEqual(code, output.ToString());

6
ILSpy/Languages/CSharpLanguage.cs

@ -212,10 +212,10 @@ namespace ICSharpCode.ILSpy
{ {
astBuilder.RunTransformations(transformAbortCondition); astBuilder.RunTransformations(transformAbortCondition);
if (additionalTransform != null) { if (additionalTransform != null) {
additionalTransform.Run(astBuilder.CompilationUnit); additionalTransform.Run(astBuilder.SyntaxTree);
} }
if (options.DecompilerSettings.ShowXmlDocumentation) { if (options.DecompilerSettings.ShowXmlDocumentation) {
AddXmlDocTransform.Run(astBuilder.CompilationUnit); AddXmlDocTransform.Run(astBuilder.SyntaxTree);
} }
astBuilder.GenerateCode(output); astBuilder.GenerateCode(output);
} }
@ -650,7 +650,7 @@ namespace ICSharpCode.ILSpy
else else
b.AddField(fd); b.AddField(fd);
b.RunTransformations(); b.RunTransformations();
foreach (var attribute in b.CompilationUnit.Descendants.OfType<AttributeSection>()) foreach (var attribute in b.SyntaxTree.Descendants.OfType<AttributeSection>())
attribute.Remove(); attribute.Remove();
StringWriter w = new StringWriter(); StringWriter w = new StringWriter();

6
ILSpy/Properties/app.config.template

@ -17,15 +17,15 @@
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ICSharpCode.NRefactory" publicKeyToken="d4bfe873e7598c49" culture="neutral"/> <assemblyIdentity name="ICSharpCode.NRefactory" publicKeyToken="d4bfe873e7598c49" culture="neutral"/>
<bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.6"/> <bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ICSharpCode.NRefactory.CSharp" publicKeyToken="d4bfe873e7598c49" culture="neutral"/> <assemblyIdentity name="ICSharpCode.NRefactory.CSharp" publicKeyToken="d4bfe873e7598c49" culture="neutral"/>
<bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.6"/> <bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ICSharpCode.NRefactory.VB" publicKeyToken="d4bfe873e7598c49" culture="neutral"/> <assemblyIdentity name="ICSharpCode.NRefactory.VB" publicKeyToken="d4bfe873e7598c49" culture="neutral"/>
<bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.6"/> <bindingRedirect oldVersion="5.0.0.0-99.9.9.9" newVersion="5.0.0.0"/>
</dependentAssembly> </dependentAssembly>
<dependentAssembly> <dependentAssembly>
<assemblyIdentity name="ICSharpCode.Decompiler" publicKeyToken="d4bfe873e7598c49" culture="neutral"/> <assemblyIdentity name="ICSharpCode.Decompiler" publicKeyToken="d4bfe873e7598c49" culture="neutral"/>

2
ILSpy/SearchPane.cs

@ -217,7 +217,7 @@ namespace ICSharpCode.ILSpy
if (1 == searchTerm.Length) if (1 == searchTerm.Length)
{ {
CSharpParser parser = new CSharpParser(); CSharpParser parser = new CSharpParser();
PrimitiveExpression pe = parser.ParseExpression(new StringReader(searchTerm[0])) as PrimitiveExpression; PrimitiveExpression pe = parser.ParseExpression(searchTerm[0]) as PrimitiveExpression;
if (pe != null && pe.Value != null) { if (pe != null && pe.Value != null) {
TypeCode peValueType = Type.GetTypeCode(pe.Value.GetType()); TypeCode peValueType = Type.GetTypeCode(pe.Value.GetType());
switch (peValueType) { switch (peValueType) {

2
ILSpy/VB/ILSpyEnvironmentProvider.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.ILSpy.VB
} }
} }
readonly CecilLoader loader = new CecilLoader(false); readonly CecilLoader loader = new CecilLoader();
public string GetTypeNameForAttribute(ICSharpCode.NRefactory.CSharp.Attribute attribute) public string GetTypeNameForAttribute(ICSharpCode.NRefactory.CSharp.Attribute attribute)
{ {

4
ILSpy/VB/VBLanguage.cs

@ -406,8 +406,8 @@ namespace ICSharpCode.ILSpy.VB
{ {
astBuilder.RunTransformations(transformAbortCondition); astBuilder.RunTransformations(transformAbortCondition);
if (options.DecompilerSettings.ShowXmlDocumentation) if (options.DecompilerSettings.ShowXmlDocumentation)
AddXmlDocTransform.Run(astBuilder.CompilationUnit); AddXmlDocTransform.Run(astBuilder.SyntaxTree);
var csharpUnit = astBuilder.CompilationUnit; var csharpUnit = astBuilder.SyntaxTree;
csharpUnit.AcceptVisitor(new NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true }); csharpUnit.AcceptVisitor(new NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true });
var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null);
var outputFormatter = new VBTextOutputFormatter(output); var outputFormatter = new VBTextOutputFormatter(output);

3
NRefactory/.gitignore vendored

@ -1,2 +1,5 @@
bin
obj
/lib/*.dll /lib/*.dll
/ICSharpCode.NRefactory.Tests/PartCover/* /ICSharpCode.NRefactory.Tests/PartCover/*
_ReSharper*/*

3
NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/.gitignore vendored

@ -1,3 +0,0 @@
bin/
obj/

22
NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -28,6 +28,26 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole> <Externalconsole>true</Externalconsole>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
</ItemGroup> </ItemGroup>

2
NRefactory/ICSharpCode.NRefactory.CSharp.AstVerifier/Main.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp.AstVerifier
if (!file.EndsWith (".cs")) if (!file.EndsWith (".cs"))
continue; continue;
string text = File.ReadAllText (file); string text = File.ReadAllText (file);
var unit = CompilationUnit.Parse (text, file); var unit = SyntaxTree.Parse (text, file);
if (unit == null) if (unit == null)
continue; continue;
string generated = unit.GetText (); string generated = unit.GetText ();

3
NRefactory/ICSharpCode.NRefactory.CSharp/.gitignore vendored

@ -1,3 +0,0 @@
bin/
obj/

1
NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/ControlFlow.cs

@ -599,6 +599,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement); ControlFlowNode bodyStart = builder.CreateStartNode(forStatement.EmbeddedStatement);
ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart); ControlFlowNode bodyEnd = forStatement.EmbeddedStatement.AcceptVisitor(this, bodyStart);
if (bodyEnd != null)
Connect(bodyEnd, iteratorStart); Connect(bodyEnd, iteratorStart);
breakTargets.Pop(); breakTargets.Pop();

4
NRefactory/ICSharpCode.NRefactory.CSharp/Analysis/DefiniteAssignmentAnalysis.cs

@ -443,7 +443,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
// the special values are valid as output only, not as input // the special values are valid as output only, not as input
Debug.Assert(data == CleanSpecialValues(data)); Debug.Assert(data == CleanSpecialValues(data));
DefiniteAssignmentStatus status = data; DefiniteAssignmentStatus status = data;
foreach (AstNode child in node.Children) { for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
analysis.analysisCancellationToken.ThrowIfCancellationRequested(); analysis.analysisCancellationToken.ThrowIfCancellationRequested();
Debug.Assert(!(child is Statement)); // statements are visited with the CFG, not with the visitor pattern Debug.Assert(!(child is Statement)); // statements are visited with the CFG, not with the visitor pattern
@ -721,7 +721,7 @@ namespace ICSharpCode.NRefactory.CSharp.Analysis
} }
DefiniteAssignmentStatus afterTrue = conditionalExpression.TrueExpression.AcceptVisitor(this, beforeTrue); DefiniteAssignmentStatus afterTrue = conditionalExpression.TrueExpression.AcceptVisitor(this, beforeTrue);
DefiniteAssignmentStatus afterFalse = conditionalExpression.TrueExpression.AcceptVisitor(this, beforeFalse); DefiniteAssignmentStatus afterFalse = conditionalExpression.FalseExpression.AcceptVisitor(this, beforeFalse);
return MergeStatus(CleanSpecialValues(afterTrue), CleanSpecialValues(afterFalse)); return MergeStatus(CleanSpecialValues(afterTrue), CleanSpecialValues(afterFalse));
} }
} }

43
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNode.cs

@ -1,4 +1,4 @@
// //
// AstNode.cs // AstNode.cs
// //
// Author: // Author:
@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // 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 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -194,13 +195,13 @@ namespace ICSharpCode.NRefactory.CSharp
/// <summary> /// <summary>
/// Gets the region from StartLocation to EndLocation for this node. /// Gets the region from StartLocation to EndLocation for this node.
/// The file name of the region is set based on the parent CompilationUnit's file name. /// The file name of the region is set based on the parent SyntaxTree's file name.
/// If this node is not connected to a whole compilation, the file name will be null. /// If this node is not connected to a whole compilation, the file name will be null.
/// </summary> /// </summary>
public ICSharpCode.NRefactory.TypeSystem.DomRegion GetRegion() public ICSharpCode.NRefactory.TypeSystem.DomRegion GetRegion()
{ {
var cu = (this.Ancestors.LastOrDefault() ?? this) as CompilationUnit; var syntaxTree = (this.Ancestors.LastOrDefault() ?? this) as SyntaxTree;
string fileName = (cu != null ? cu.FileName : null); string fileName = (syntaxTree != null ? syntaxTree.FileName : null);
return new ICSharpCode.NRefactory.TypeSystem.DomRegion(fileName, this.StartLocation, this.EndLocation); return new ICSharpCode.NRefactory.TypeSystem.DomRegion(fileName, this.StartLocation, this.EndLocation);
} }
@ -288,17 +289,31 @@ namespace ICSharpCode.NRefactory.CSharp
/// Gets all descendants of this node (excluding this node itself). /// Gets all descendants of this node (excluding this node itself).
/// </summary> /// </summary>
public IEnumerable<AstNode> Descendants { public IEnumerable<AstNode> Descendants {
get { get { return GetDescendants(false); }
return Utils.TreeTraversal.PreOrder (this.Children, n => n.Children);
}
} }
/// <summary> /// <summary>
/// Gets all descendants of this node (including this node itself). /// Gets all descendants of this node (including this node itself).
/// </summary> /// </summary>
public IEnumerable<AstNode> DescendantsAndSelf { public IEnumerable<AstNode> DescendantsAndSelf {
get { get { return GetDescendants(true); }
return Utils.TreeTraversal.PreOrder (this, n => n.Children); }
IEnumerable<AstNode> GetDescendants(bool includeSelf)
{
if (includeSelf)
yield return this;
Stack<AstNode> nextStack = new Stack<AstNode>();
nextStack.Push(null);
AstNode pos = firstChild;
while (pos != null) {
if (pos.nextSibling != null)
nextStack.Push(pos.nextSibling);
yield return pos;
if (pos.firstChild != null)
pos = pos.firstChild;
else
pos = nextStack.Pop();
} }
} }
@ -367,13 +382,6 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public void InsertChildsBefore<T>(AstNode nextSibling, Role<T> role, params T[] child) where T : AstNode
{
foreach (var cur in child) {
InsertChildBefore(nextSibling, cur, role);
}
}
public void InsertChildBefore<T> (AstNode nextSibling, T child, Role<T> role) where T : AstNode public void InsertChildBefore<T> (AstNode nextSibling, T child, Role<T> role) where T : AstNode
{ {
if (role == null) if (role == null)
@ -483,7 +491,7 @@ namespace ICSharpCode.NRefactory.CSharp
newNode.SetRole(this.Role); newNode.SetRole(this.Role);
newNode.prevSibling = prevSibling; newNode.prevSibling = prevSibling;
newNode.nextSibling = nextSibling; newNode.nextSibling = nextSibling;
if (parent != null) {
if (prevSibling != null) { if (prevSibling != null) {
Debug.Assert (prevSibling.nextSibling == this); Debug.Assert (prevSibling.nextSibling == this);
prevSibling.nextSibling = newNode; prevSibling.nextSibling = newNode;
@ -502,7 +510,6 @@ namespace ICSharpCode.NRefactory.CSharp
prevSibling = null; prevSibling = null;
nextSibling = null; nextSibling = null;
} }
}
public AstNode ReplaceWith (Func<AstNode, AstNode> replaceFunction) public AstNode ReplaceWith (Func<AstNode, AstNode> replaceFunction)
{ {

16
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs

@ -204,5 +204,21 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
node.InsertChildBefore(existingItem, newItem, role); node.InsertChildBefore(existingItem, newItem, role);
} }
/// <summary>
/// Applies the <paramref name="visitor"/> to all nodes in this collection.
/// </summary>
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);
}
}
} }
} }

6
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/AstType.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull; return other == null || other.IsNull;
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode) public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{ {
return SpecialType.UnknownType; return SpecialType.UnknownType;
} }
@ -99,7 +99,7 @@ namespace ICSharpCode.NRefactory.CSharp
return visitor.VisitPatternPlaceholder (this, child, data); return visitor.VisitPatternPlaceholder (this, child, data);
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode) public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
} }
@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// For resolving simple names, the current namespace and usings from the CurrentUsingScope /// For resolving simple names, the current namespace and usings from the CurrentUsingScope
/// (on CSharpTypeResolveContext only) is used. /// (on CSharpTypeResolveContext only) is used.
/// </remarks> /// </remarks>
public abstract ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type); public abstract ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type);
/// <summary> /// <summary>
/// Creates a pointer type from this type by nesting it in a <see cref="ComposedType"/>. /// Creates a pointer type from this type by nesting it in a <see cref="ComposedType"/>.

50
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CSharpUtil.cs

@ -51,28 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp
if (condition is BinaryOperatorExpression) { if (condition is BinaryOperatorExpression) {
var bOp = (BinaryOperatorExpression)condition; var bOp = (BinaryOperatorExpression)condition;
switch (bOp.Operator) { var negatedOp = NegateRelationalOperator (bOp.Operator);
case BinaryOperatorType.GreaterThan: if (negatedOp == BinaryOperatorType.Any)
bOp.Operator = BinaryOperatorType.LessThanOrEqual;
return bOp;
case BinaryOperatorType.GreaterThanOrEqual:
bOp.Operator = BinaryOperatorType.LessThan;
return bOp;
case BinaryOperatorType.Equality:
bOp.Operator = BinaryOperatorType.InEquality;
return bOp;
case BinaryOperatorType.InEquality:
bOp.Operator = BinaryOperatorType.Equality;
return bOp;
case BinaryOperatorType.LessThan:
bOp.Operator = BinaryOperatorType.GreaterThanOrEqual;
return bOp;
case BinaryOperatorType.LessThanOrEqual:
bOp.Operator = BinaryOperatorType.GreaterThan;
return bOp;
default:
return new UnaryOperatorExpression (UnaryOperatorType.Not, new ParenthesizedExpression (condition)); return new UnaryOperatorExpression (UnaryOperatorType.Not, new ParenthesizedExpression (condition));
} bOp.Operator = negatedOp;
return bOp;
} }
if (condition is ConditionalExpression) { if (condition is ConditionalExpression) {
var cEx = condition as ConditionalExpression; var cEx = condition as ConditionalExpression;
@ -88,6 +71,31 @@ namespace ICSharpCode.NRefactory.CSharp
return new UnaryOperatorExpression (UnaryOperatorType.Not, condition); return new UnaryOperatorExpression (UnaryOperatorType.Not, condition);
} }
/// <summary>
/// Get negation of the specified relational operator
/// </summary>
/// <returns>
/// negation of the specified relational operator, or BinaryOperatorType.Any if it's not a relational operator
/// </returns>
public static BinaryOperatorType NegateRelationalOperator (BinaryOperatorType op)
{
switch (op) {
case BinaryOperatorType.GreaterThan:
return BinaryOperatorType.LessThanOrEqual;
case BinaryOperatorType.GreaterThanOrEqual:
return BinaryOperatorType.LessThan;
case BinaryOperatorType.Equality:
return BinaryOperatorType.InEquality;
case BinaryOperatorType.InEquality:
return BinaryOperatorType.Equality;
case BinaryOperatorType.LessThan:
return BinaryOperatorType.GreaterThanOrEqual;
case BinaryOperatorType.LessThanOrEqual:
return BinaryOperatorType.GreaterThan;
}
return BinaryOperatorType.Any;
}
} }
} }

2
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ComposedType.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.CSharp
return this; return this;
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type) public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{ {
ITypeReference t = this.BaseType.ToTypeReference(lookupMode); ITypeReference t = this.BaseType.ToTypeReference(lookupMode);
if (this.HasNullableSpecifier) { if (this.HasNullableSpecifier) {

8
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/DepthFirstAstVisitor.cs

@ -44,9 +44,9 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public virtual void VisitCompilationUnit (CompilationUnit unit) public virtual void VisitSyntaxTree (SyntaxTree syntaxTree)
{ {
VisitChildren (unit); VisitChildren (syntaxTree);
} }
public virtual void VisitComment(Comment comment) public virtual void VisitComment(Comment comment)
@ -642,7 +642,7 @@ namespace ICSharpCode.NRefactory.CSharp
return default (T); return default (T);
} }
public virtual T VisitCompilationUnit (CompilationUnit unit) public virtual T VisitSyntaxTree (SyntaxTree unit)
{ {
return VisitChildren (unit); return VisitChildren (unit);
} }
@ -1240,7 +1240,7 @@ namespace ICSharpCode.NRefactory.CSharp
return default (S); return default (S);
} }
public virtual S VisitCompilationUnit (CompilationUnit unit, T data) public virtual S VisitSyntaxTree (SyntaxTree unit, T data)
{ {
return VisitChildren (unit, data); return VisitChildren (unit, data);
} }

75
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/ArrayInitializerExpression.cs

@ -33,6 +33,18 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public class ArrayInitializerExpression : Expression public class ArrayInitializerExpression : Expression
{ {
/// <summary>
/// For ease of use purposes in the resolver the ast representation
/// of { a, b, c } is { {a}, {b}, {c} }.
/// If IsSingleElement is true then this array initializer expression is a generated one.
/// That has no meaning in the source code (and contains no brace tokens).
/// </summary>
public virtual bool IsSingleElement {
get {
return false;
}
}
public ArrayInitializerExpression() public ArrayInitializerExpression()
{ {
} }
@ -111,6 +123,69 @@ namespace ICSharpCode.NRefactory.CSharp
ArrayInitializerExpression o = other as ArrayInitializerExpression; ArrayInitializerExpression o = other as ArrayInitializerExpression;
return o != null && this.Elements.DoMatch(o.Elements, match); return o != null && this.Elements.DoMatch(o.Elements, match);
} }
public static ArrayInitializerExpression CreateSingleElementInitializer ()
{
return new SingleArrayInitializerExpression();
}
/// <summary>
/// Single elements in array initializers are represented with this special class.
/// </summary>
class SingleArrayInitializerExpression : ArrayInitializerExpression
{
public override bool IsSingleElement {
get {
return true;
}
}
}
#region PatternPlaceholder
public static implicit operator ArrayInitializerExpression(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : ArrayInitializerExpression, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override NodeType NodeType {
get { return NodeType.Pattern; }
}
public override void AcceptVisitor (IAstVisitor visitor)
{
visitor.VisitPatternPlaceholder(this, child);
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return visitor.VisitPatternPlaceholder(this, child);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
} }
} }

9
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/IdentifierExpression.cs

@ -56,6 +56,15 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public Identifier IdentifierToken {
get {
return GetChildByRole (Roles.Identifier);
}
set {
SetChildByRole (Roles.Identifier, value);
}
}
public AstNodeCollection<AstType> TypeArguments { public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); } get { return GetChildrenByRole (Roles.TypeArgument); }
} }

12
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/MemberReferenceExpression.cs

@ -34,8 +34,16 @@ namespace ICSharpCode.NRefactory.CSharp
public class MemberReferenceExpression : Expression public class MemberReferenceExpression : Expression
{ {
public Expression Target { public Expression Target {
get { return GetChildByRole (Roles.TargetExpression); } get {
set { SetChildByRole(Roles.TargetExpression, value); } return GetChildByRole(Roles.TargetExpression);
}
set {
SetChildByRole(Roles.TargetExpression, value);
}
}
public CSharpTokenNode DotToken {
get { return GetChildByRole (Roles.Dot); }
} }
public string MemberName { public string MemberName {

10
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedArgumentExpression.cs

@ -30,13 +30,13 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
} }
public NamedArgumentExpression(string identifier, Expression expression) public NamedArgumentExpression(string name, Expression expression)
{ {
this.Identifier = identifier; this.Name = name;
this.Expression = expression; this.Expression = expression;
} }
public string Identifier { public string Name {
get { get {
return GetChildByRole (Roles.Identifier).Name; return GetChildByRole (Roles.Identifier).Name;
} }
@ -45,7 +45,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public Identifier IdentifierToken { public Identifier NameToken {
get { get {
return GetChildByRole (Roles.Identifier); return GetChildByRole (Roles.Identifier);
} }
@ -81,7 +81,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
NamedArgumentExpression o = other as NamedArgumentExpression; NamedArgumentExpression o = other as NamedArgumentExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match); return o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);
} }
} }
} }

10
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/NamedExpression.cs

@ -40,13 +40,13 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
} }
public NamedExpression (string identifier, Expression expression) public NamedExpression (string name, Expression expression)
{ {
this.Identifier = identifier; this.Name = name;
this.Expression = expression; this.Expression = expression;
} }
public string Identifier { public string Name {
get { get {
return GetChildByRole (Roles.Identifier).Name; return GetChildByRole (Roles.Identifier).Name;
} }
@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public Identifier IdentifierToken { public Identifier NameToken {
get { get {
return GetChildByRole (Roles.Identifier); return GetChildByRole (Roles.Identifier);
} }
@ -91,7 +91,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
var o = other as NamedExpression; var o = other as NamedExpression;
return o != null && MatchString(this.Identifier, o.Identifier) && this.Expression.DoMatch(o.Expression, match); return o != null && MatchString(this.Name, o.Name) && this.Expression.DoMatch(o.Expression, match);
} }
} }
} }

11
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Expressions/PointerReferenceExpression.cs

@ -49,7 +49,16 @@ namespace ICSharpCode.NRefactory.CSharp
return GetChildByRole (Roles.Identifier).Name; return GetChildByRole (Roles.Identifier).Name;
} }
set { set {
SetChildByRole(Roles.Identifier, Identifier.Create (value)); SetChildByRole(Roles.Identifier, Identifier.Create (value));
}
}
public Identifier MemberNameToken {
get {
return GetChildByRole (Roles.Identifier);
}
set {
SetChildByRole (Roles.Identifier, value);
} }
} }

2
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/NamespaceDeclaration.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public class NamespaceDeclaration : AstNode public class NamespaceDeclaration : AstNode
{ {
public static readonly Role<AstNode> MemberRole = CompilationUnit.MemberRole; public static readonly Role<AstNode> MemberRole = SyntaxTree.MemberRole;
public override NodeType NodeType { public override NodeType NodeType {
get { get {

6
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/GeneralScope/PreProcessorDirective.cs

@ -93,6 +93,12 @@ namespace ICSharpCode.NRefactory.CSharp
this.endLocation = endLocation; this.endLocation = endLocation;
} }
public PreProcessorDirective(PreProcessorDirectiveType type, string argument = null)
{
this.Type = type;
this.Argument = argument;
}
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitPreProcessorDirective (this); visitor.VisitPreProcessorDirective (this);

6
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/IAstVisitor.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.NRefactory.CSharp
void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration); void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);
void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer); void VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);
void VisitCompilationUnit(CompilationUnit compilationUnit); void VisitSyntaxTree(SyntaxTree syntaxTree);
void VisitSimpleType(SimpleType simpleType); void VisitSimpleType(SimpleType simpleType);
void VisitMemberType(MemberType memberType); void VisitMemberType(MemberType memberType);
void VisitComposedType(ComposedType composedType); void VisitComposedType(ComposedType composedType);
@ -260,7 +260,7 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration); S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration);
S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer); S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer);
S VisitCompilationUnit(CompilationUnit compilationUnit); S VisitSyntaxTree(SyntaxTree syntaxTree);
S VisitSimpleType(SimpleType simpleType); S VisitSimpleType(SimpleType simpleType);
S VisitMemberType(MemberType memberType); S VisitMemberType(MemberType memberType);
S VisitComposedType(ComposedType composedType); S VisitComposedType(ComposedType composedType);
@ -391,7 +391,7 @@ namespace ICSharpCode.NRefactory.CSharp
S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration, T data); S VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration, T data);
S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer, T data); S VisitFixedVariableInitializer(FixedVariableInitializer fixedVariableInitializer, T data);
S VisitCompilationUnit(CompilationUnit compilationUnit, T data); S VisitSyntaxTree(SyntaxTree syntaxTree, T data);
S VisitSimpleType(SimpleType simpleType, T data); S VisitSimpleType(SimpleType simpleType, T data);
S VisitMemberType(MemberType memberType, T data); S VisitMemberType(MemberType memberType, T data);
S VisitComposedType(ComposedType composedType, T data); S VisitComposedType(ComposedType composedType, T data);

4
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/MemberType.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString(); return b.ToString();
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type) public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{ {
TypeOrNamespaceReference t; TypeOrNamespaceReference t;
if (this.IsDoubleColon) { if (this.IsDoubleColon) {
@ -154,7 +154,7 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (var ta in this.TypeArguments) { foreach (var ta in this.TypeArguments) {
typeArguments.Add(ta.ToTypeReference(lookupMode)); typeArguments.Add(ta.ToTypeReference(lookupMode));
} }
return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments); return new MemberTypeOrNamespaceReference(t, this.MemberName, typeArguments, lookupMode);
} }
} }
} }

1054
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/ObservableAstVisitor.cs

File diff suppressed because it is too large Load Diff

2
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/PrimitiveType.cs

@ -103,7 +103,7 @@ namespace ICSharpCode.NRefactory.CSharp
return Keyword; return Keyword;
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type) public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{ {
KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword); KnownTypeCode typeCode = GetTypeCodeForPrimitiveType(this.Keyword);
if (typeCode == KnownTypeCode.None) if (typeCode == KnownTypeCode.None)

4
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SimpleType.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.NRefactory.CSharp
return other == null || other.IsNull; return other == null || other.IsNull;
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode) public override ITypeReference ToTypeReference(NameLookupMode lookupMode)
{ {
return SpecialType.UnknownType; return SpecialType.UnknownType;
} }
@ -158,7 +158,7 @@ namespace ICSharpCode.NRefactory.CSharp
return b.ToString(); return b.ToString();
} }
public override ITypeReference ToTypeReference(SimpleNameLookupMode lookupMode = SimpleNameLookupMode.Type) public override ITypeReference ToTypeReference(NameLookupMode lookupMode = NameLookupMode.Type)
{ {
var typeArguments = new List<ITypeReference>(); var typeArguments = new List<ITypeReference>();
foreach (var ta in this.TypeArguments) { foreach (var ta in this.TypeArguments) {

34
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/Statements/TryCatchStatement.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public static readonly TokenRole TryKeywordRole = new TokenRole ("try"); public static readonly TokenRole TryKeywordRole = new TokenRole ("try");
public static readonly Role<BlockStatement> TryBlockRole = new Role<BlockStatement>("TryBlock", BlockStatement.Null); public static readonly Role<BlockStatement> TryBlockRole = new Role<BlockStatement>("TryBlock", BlockStatement.Null);
public static readonly Role<CatchClause> CatchClauseRole = new Role<CatchClause>("CatchClause"); public static readonly Role<CatchClause> CatchClauseRole = new Role<CatchClause>("CatchClause", CatchClause.Null);
public static readonly TokenRole FinallyKeywordRole = new TokenRole ("finally"); public static readonly TokenRole FinallyKeywordRole = new TokenRole ("finally");
public static readonly Role<BlockStatement> FinallyBlockRole = new Role<BlockStatement>("FinallyBlock", BlockStatement.Null); public static readonly Role<BlockStatement> FinallyBlockRole = new Role<BlockStatement>("FinallyBlock", BlockStatement.Null);
@ -91,6 +91,38 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public static readonly TokenRole CatchKeywordRole = new TokenRole ("catch"); public static readonly TokenRole CatchKeywordRole = new TokenRole ("catch");
#region Null
public new static readonly CatchClause Null = new NullCatchClause ();
sealed class NullCatchClause : CatchClause
{
public override bool IsNull {
get {
return true;
}
}
public override void AcceptVisitor (IAstVisitor visitor)
{
}
public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{
return default (T);
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder #region PatternPlaceholder
public static implicit operator CatchClause(PatternMatching.Pattern pattern) public static implicit operator CatchClause(PatternMatching.Pattern pattern)
{ {

81
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/CompilationUnit.cs → NRefactory/ICSharpCode.NRefactory.CSharp/Ast/SyntaxTree.cs

@ -1,5 +1,5 @@
// //
// CompilationUnit.cs // SyntaxTree.cs
// //
// Author: // Author:
// Mike Krüger <mkrueger@novell.com> // Mike Krüger <mkrueger@novell.com>
@ -23,6 +23,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // 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 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.Resolver;
@ -35,7 +36,10 @@ using ICSharpCode.NRefactory.Editor;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public class CompilationUnit : AstNode [Obsolete("CompilationUnit was renamed to SyntaxTree", true)]
public class CompilationUnit {}
public class SyntaxTree : AstNode
{ {
public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null); public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null);
@ -48,7 +52,7 @@ namespace ICSharpCode.NRefactory.CSharp
string fileName; string fileName;
/// <summary> /// <summary>
/// Gets/Sets the file name of this compilation unit. /// Gets/Sets the file name of this syntax tree.
/// </summary> /// </summary>
public string FileName { public string FileName {
get { return fileName; } get { return fileName; }
@ -62,25 +66,42 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildrenByRole(MemberRole); } get { return GetChildrenByRole(MemberRole); }
} }
IList<string> conditionalSymbols = null;
List<Error> errors = new List<Error> (); List<Error> errors = new List<Error> ();
public List<Error> Errors { public List<Error> Errors {
get { return errors; } get { return errors; }
} }
/// <summary>
/// Gets the conditional symbols used to parse the source file. Note that this list contains
/// the conditional symbols at the start of the first token in the file - including the ones defined
/// in the source file.
/// </summary>
public IList<string> ConditionalSymbols {
get {
return conditionalSymbols ?? EmptyList<string>.Instance;
}
internal set {
conditionalSymbols = value;
}
}
/// <summary> /// <summary>
/// Gets the expression that was on top of the parse stack. /// Gets the expression that was on top of the parse stack.
/// This is the only way to get an expression that isn't part of a statment. /// This is the only way to get an expression that isn't part of a statment.
/// (eg. when an error follows an expression). /// (eg. when an error follows an expression).
/// ///
/// This is used for code completion to 'get the expression before a token - like ., <, ('. /// This is used for code completion to 'get the expression before a token - like ., &lt;, ('.
/// </summary> /// </summary>
public AstNode TopExpression { public AstNode TopExpression {
get; get;
internal set; internal set;
} }
public CompilationUnit () public SyntaxTree ()
{ {
} }
@ -103,67 +124,59 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
CompilationUnit o = other as CompilationUnit; SyntaxTree o = other as SyntaxTree;
return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match); return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match);
} }
public override void AcceptVisitor (IAstVisitor visitor) public override void AcceptVisitor (IAstVisitor visitor)
{ {
visitor.VisitCompilationUnit (this); visitor.VisitSyntaxTree (this);
} }
public override T AcceptVisitor<T> (IAstVisitor<T> visitor) public override T AcceptVisitor<T> (IAstVisitor<T> visitor)
{ {
return visitor.VisitCompilationUnit (this); return visitor.VisitSyntaxTree (this);
} }
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data) public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{ {
return visitor.VisitCompilationUnit (this, data); return visitor.VisitSyntaxTree (this, data);
} }
/// <summary> /// <summary>
/// Converts this compilation unit into a parsed file that can be stored in the type system. /// Converts this syntax tree into a parsed file that can be stored in the type system.
/// </summary> /// </summary>
public CSharpParsedFile ToTypeSystem () public CSharpUnresolvedFile ToTypeSystem ()
{ {
if (string.IsNullOrEmpty (this.FileName)) if (string.IsNullOrEmpty (this.FileName))
throw new InvalidOperationException ("Cannot use ToTypeSystem() on a compilation unit without file name."); throw new InvalidOperationException ("Cannot use ToTypeSystem() on a syntax tree without file name.");
var v = new TypeSystemConvertVisitor (this.FileName); var v = new TypeSystemConvertVisitor (this.FileName);
v.VisitCompilationUnit (this); v.VisitSyntaxTree (this);
return v.ParsedFile; return v.UnresolvedFile;
} }
public static CompilationUnit Parse (string text, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) public static SyntaxTree Parse (string program, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{ {
var parser = new CSharpParser (); var parser = new CSharpParser (settings);
if (settings != null) return parser.Parse (program, fileName);
parser.CompilerSettings = settings;
return parser.Parse (text, fileName);
} }
public static CompilationUnit Parse (TextReader reader, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) public static SyntaxTree Parse (TextReader reader, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{ {
var parser = new CSharpParser (); var parser = new CSharpParser (settings);
if (settings != null) return parser.Parse (reader, fileName);
parser.CompilerSettings = settings;
return parser.Parse (reader, fileName, 0);
} }
public static CompilationUnit Parse (Stream stream, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) public static SyntaxTree Parse (Stream stream, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{ {
var parser = new CSharpParser (); var parser = new CSharpParser (settings);
if (settings != null) return parser.Parse (stream, fileName);
parser.CompilerSettings = settings;
return parser.Parse (stream, fileName, 0);
} }
public static CompilationUnit Parse (ITextSource textSource, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken)) public static SyntaxTree Parse (ITextSource textSource, string fileName = "", CompilerSettings settings = null, CancellationToken cancellationToken = default (CancellationToken))
{ {
var parser = new CSharpParser (); var parser = new CSharpParser (settings);
if (settings != null) return parser.Parse (textSource, fileName);
parser.CompilerSettings = settings;
return parser.Parse (textSource, fileName, 0);
} }
} }
} }

13
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/TypeMembers/IndexerDeclaration.cs

@ -24,6 +24,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
using System;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
@ -47,6 +48,16 @@ namespace ICSharpCode.NRefactory.CSharp
set { SetChildByRole (PrivateImplementationTypeRole, value); } set { SetChildByRole (PrivateImplementationTypeRole, value); }
} }
public override string Name {
get { return "Item"; }
set { throw new NotSupportedException(); }
}
public override Identifier NameToken {
get { return Identifier.Null; }
set { throw new NotSupportedException(); }
}
public CSharpTokenNode LBracketToken { public CSharpTokenNode LBracketToken {
get { return GetChildByRole (Roles.LBracket); } get { return GetChildByRole (Roles.LBracket); }
} }
@ -95,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{ {
IndexerDeclaration o = other as IndexerDeclaration; IndexerDeclaration o = other as IndexerDeclaration;
return o != null && MatchString(this.Name, o.Name) return o != null
&& this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match) && this.MatchAttributesAndModifiers(o, match) && this.ReturnType.DoMatch(o.ReturnType, match)
&& this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match) && this.PrivateImplementationType.DoMatch(o.PrivateImplementationType, match)
&& this.Parameters.DoMatch(o.Parameters, match) && this.Parameters.DoMatch(o.Parameters, match)

1201
NRefactory/ICSharpCode.NRefactory.CSharp/Ast/old_ObservableAstVisitor.cs

File diff suppressed because it is too large Load Diff

134
NRefactory/ICSharpCode.NRefactory.CSharp/CSharpProjectContent.cs

@ -31,35 +31,58 @@ namespace ICSharpCode.NRefactory.CSharp
public class CSharpProjectContent : IProjectContent public class CSharpProjectContent : IProjectContent
{ {
string assemblyName; string assemblyName;
Dictionary<string, IParsedFile> parsedFiles; string projectFileName;
string location;
Dictionary<string, IUnresolvedFile> unresolvedFiles;
List<IAssemblyReference> assemblyReferences; List<IAssemblyReference> assemblyReferences;
CompilerSettings compilerSettings;
public CSharpProjectContent() public CSharpProjectContent()
{ {
this.assemblyName = string.Empty; this.unresolvedFiles = new Dictionary<string, IUnresolvedFile>(Platform.FileNameComparer);
this.parsedFiles = new Dictionary<string, IParsedFile>(Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>(); this.assemblyReferences = new List<IAssemblyReference>();
this.compilerSettings = new CompilerSettings();
compilerSettings.Freeze();
} }
protected CSharpProjectContent(CSharpProjectContent pc) protected CSharpProjectContent(CSharpProjectContent pc)
{ {
this.assemblyName = pc.assemblyName; this.assemblyName = pc.assemblyName;
this.parsedFiles = new Dictionary<string, IParsedFile>(pc.parsedFiles, Platform.FileNameComparer); this.projectFileName = pc.projectFileName;
this.location = pc.location;
this.unresolvedFiles = new Dictionary<string, IUnresolvedFile>(pc.unresolvedFiles, Platform.FileNameComparer);
this.assemblyReferences = new List<IAssemblyReference>(pc.assemblyReferences); this.assemblyReferences = new List<IAssemblyReference>(pc.assemblyReferences);
this.compilerSettings = pc.compilerSettings;
} }
public IEnumerable<IParsedFile> Files { public IEnumerable<IUnresolvedFile> Files {
get { return parsedFiles.Values; } get { return unresolvedFiles.Values; }
} }
public IEnumerable<IAssemblyReference> AssemblyReferences { public IEnumerable<IAssemblyReference> AssemblyReferences {
get { return assemblyReferences; } get { return assemblyReferences; }
} }
public string ProjectFileName {
get { return projectFileName; }
}
public string AssemblyName { public string AssemblyName {
get { return assemblyName; } get { return assemblyName; }
} }
public string Location {
get { return location; }
}
public CompilerSettings CompilerSettings {
get { return compilerSettings; }
}
object IProjectContent.CompilerSettings {
get { return compilerSettings; }
}
public IEnumerable<IUnresolvedAttribute> AssemblyAttributes { public IEnumerable<IUnresolvedAttribute> AssemblyAttributes {
get { get {
return this.Files.SelectMany(f => f.AssemblyAttributes); return this.Files.SelectMany(f => f.AssemblyAttributes);
@ -78,10 +101,10 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public IParsedFile GetFile(string fileName) public IUnresolvedFile GetFile(string fileName)
{ {
IParsedFile file; IUnresolvedFile file;
if (parsedFiles.TryGetValue(fileName, out file)) if (unresolvedFiles.TryGetValue(fileName, out file))
return file; return file;
else else
return null; return null;
@ -112,7 +135,36 @@ namespace ICSharpCode.NRefactory.CSharp
return pc; return pc;
} }
public IProjectContent SetProjectFileName(string newProjectFileName)
{
CSharpProjectContent pc = Clone();
pc.projectFileName = newProjectFileName;
return pc;
}
public IProjectContent SetLocation(string newLocation)
{
CSharpProjectContent pc = Clone();
pc.location = newLocation;
return pc;
}
public IProjectContent SetCompilerSettings(object compilerSettings)
{
if (!(compilerSettings is CompilerSettings))
throw new ArgumentException("Settings must be an instance of " + typeof(CompilerSettings).FullName, "compilerSettings");
CSharpProjectContent pc = Clone();
pc.compilerSettings = (CompilerSettings)compilerSettings;
pc.compilerSettings.Freeze();
return pc;
}
public IProjectContent AddAssemblyReferences(IEnumerable<IAssemblyReference> references) public IProjectContent AddAssemblyReferences(IEnumerable<IAssemblyReference> references)
{
return AddAssemblyReferences(references.ToArray());
}
public IProjectContent AddAssemblyReferences(params IAssemblyReference[] references)
{ {
CSharpProjectContent pc = Clone(); CSharpProjectContent pc = Clone();
pc.assemblyReferences.AddRange(references); pc.assemblyReferences.AddRange(references);
@ -120,13 +172,62 @@ namespace ICSharpCode.NRefactory.CSharp
} }
public IProjectContent RemoveAssemblyReferences(IEnumerable<IAssemblyReference> references) public IProjectContent RemoveAssemblyReferences(IEnumerable<IAssemblyReference> references)
{
return RemoveAssemblyReferences(references.ToArray());
}
public IProjectContent RemoveAssemblyReferences(params IAssemblyReference[] references)
{
CSharpProjectContent pc = Clone();
foreach (var r in references)
pc.assemblyReferences.Remove(r);
return pc;
}
/// <summary>
/// Adds the specified files to the project content.
/// If a file with the same name already exists, updated the existing file.
/// </summary>
public IProjectContent AddOrUpdateFiles(IEnumerable<IUnresolvedFile> newFiles)
{ {
CSharpProjectContent pc = Clone(); CSharpProjectContent pc = Clone();
pc.assemblyReferences.RemoveAll(r => references.Contains(r)); foreach (var file in newFiles) {
pc.unresolvedFiles[file.FileName] = file;
}
return pc; return pc;
} }
public IProjectContent UpdateProjectContent(IParsedFile oldFile, IParsedFile newFile) /// <summary>
/// Adds the specified files to the project content.
/// If a file with the same name already exists, this method updates the existing file.
/// </summary>
public IProjectContent AddOrUpdateFiles(params IUnresolvedFile[] newFiles)
{
return AddOrUpdateFiles((IEnumerable<IUnresolvedFile>)newFiles);
}
/// <summary>
/// Removes the files with the specified names.
/// </summary>
public IProjectContent RemoveFiles(IEnumerable<string> fileNames)
{
CSharpProjectContent pc = Clone();
foreach (var fileName in fileNames) {
pc.unresolvedFiles.Remove(fileName);
}
return pc;
}
/// <summary>
/// Removes the files with the specified names.
/// </summary>
public IProjectContent RemoveFiles(params string[] fileNames)
{
return RemoveFiles((IEnumerable<string>)fileNames);
}
[Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")]
public IProjectContent UpdateProjectContent(IUnresolvedFile oldFile, IUnresolvedFile newFile)
{ {
if (oldFile == null && newFile == null) if (oldFile == null && newFile == null)
return this; return this;
@ -136,23 +237,24 @@ namespace ICSharpCode.NRefactory.CSharp
} }
CSharpProjectContent pc = Clone(); CSharpProjectContent pc = Clone();
if (newFile == null) if (newFile == null)
pc.parsedFiles.Remove(oldFile.FileName); pc.unresolvedFiles.Remove(oldFile.FileName);
else else
pc.parsedFiles[newFile.FileName] = newFile; pc.unresolvedFiles[newFile.FileName] = newFile;
return pc; return pc;
} }
public IProjectContent UpdateProjectContent(IEnumerable<IParsedFile> oldFiles, IEnumerable<IParsedFile> newFiles) [Obsolete("Use RemoveFiles/AddOrUpdateFiles instead")]
public IProjectContent UpdateProjectContent(IEnumerable<IUnresolvedFile> oldFiles, IEnumerable<IUnresolvedFile> newFiles)
{ {
CSharpProjectContent pc = Clone(); CSharpProjectContent pc = Clone();
if (oldFiles != null) { if (oldFiles != null) {
foreach (var oldFile in oldFiles) { foreach (var oldFile in oldFiles) {
pc.parsedFiles.Remove(oldFile.FileName); pc.unresolvedFiles.Remove(oldFile.FileName);
} }
} }
if (newFiles != null) { if (newFiles != null) {
foreach (var newFile in newFiles) { foreach (var newFile in newFiles) {
pc.parsedFiles.Add(newFile.FileName, newFile); pc.unresolvedFiles.Add(newFile.FileName, newFile);
} }
} }
return pc; return pc;

1095
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs

File diff suppressed because it is too large Load Diff

389
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngineBase.cs

@ -51,10 +51,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
#region Input properties #region Input properties
public CSharpTypeResolveContext ctx { get; private set; } public CSharpTypeResolveContext ctx { get; private set; }
public CompilationUnit Unit { get; private set; }
public CSharpParsedFile CSharpParsedFile { get; private set; }
public IProjectContent ProjectContent { get; private set; } public IProjectContent ProjectContent { get; private set; }
ICompilation compilation; ICompilation compilation;
@ -68,40 +64,36 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
#endregion #endregion
protected CSharpCompletionEngineBase (IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile) protected CSharpCompletionEngineBase(IProjectContent content, ICompletionContextProvider completionContextProvider, CSharpTypeResolveContext ctx)
{ {
if (content == null) if (content == null)
throw new ArgumentNullException("content"); throw new ArgumentNullException("content");
if (ctx == null) if (ctx == null)
throw new ArgumentNullException("ctx"); throw new ArgumentNullException("ctx");
if (unit == null) if (completionContextProvider == null)
throw new ArgumentNullException ("unit"); throw new ArgumentNullException("completionContextProvider");
if (parsedFile == null)
throw new ArgumentNullException ("parsedFile");
this.ProjectContent = content; this.ProjectContent = content;
this.CompletionContextProvider = completionContextProvider;
this.ctx = ctx; this.ctx = ctx;
this.Unit = unit;
this.CSharpParsedFile = parsedFile;
} }
public IMemberProvider MemberProvider { public ICompletionContextProvider CompletionContextProvider {
get; get;
set; private set;
} }
protected void SetOffset (int offset) public void SetOffset (int offset)
{ {
Reset (); Reset ();
this.offset = offset; this.offset = offset;
this.location = document.GetLocation (offset); this.location = document.GetLocation (offset);
var provider = MemberProvider ?? new DefaultMemberProvider (this); CompletionContextProvider.GetCurrentMembers (offset, out currentType, out currentMember);
provider.GetCurrentMembers (offset, out currentType, out currentMember);
} }
protected bool GetParameterCompletionCommandOffset(out int cpos) public bool GetParameterCompletionCommandOffset (out int cpos)
{ {
// Start calculating the parameter offset from the beginning of the // Start calculating the parameter offset from the beginning of the
// current member, instead of the beginning of the file. // current member, instead of the beginning of the file.
@ -131,7 +123,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
chevronDepth = 0; chevronDepth = 0;
} }
if (indexStack.Count == 0 && (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<')) { if (indexStack.Count == 0 && (parenDepth == 0 && c == '(' || chevronDepth == 0 && c == '<')) {
int p = GetCurrentParameterIndex (cpos + 1, startPos); int p = GetCurrentParameterIndex (startPos, cpos + 1);
if (p != -1) { if (p != -1) {
cpos++; cpos++;
return true; return true;
@ -154,94 +146,144 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return false; return false;
} }
protected int GetCurrentParameterIndex (int offset, int memberStart) public int GetCurrentParameterIndex (int triggerOffset, int endOffset)
{ {
int cursor = this.offset; char lastChar = document.GetCharAt (endOffset - 1);
int i = offset; if (lastChar == '(' || lastChar == '<') {
return 0;
if (i > cursor) { }
var parameter = new Stack<int> ();
var bracketStack = new Stack<Stack<int>> ();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
for (int i = triggerOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
char nextCh = i + 1 < document.TextLength ? document.GetCharAt (i + 1) : '\0';
switch (ch) {
case '{':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
bracketStack.Push (parameter);
parameter = new Stack<int> ();
break;
case '[':
case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push (0);
break;
case '}':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (bracketStack.Count > 0) {
parameter = bracketStack.Pop ();
} else {
return -1; return -1;
} }
if (i == cursor) { break;
return 1; case ']':
case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop ();
} else {
return -1;
} }
// parameters are 1 based break;
int index = memberStart + 1; case '<':
int parentheses = 0; if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
int bracket = 0; break;
bool insideQuote = false, insideString = false, insideSingleLineComment = false, insideMultiLineComment = false;
Stack<int> indexStack = new Stack<int> ();
do {
char c = document.GetCharAt (i - 1);
switch (c) {
case '\\':
if (insideString || insideQuote) {
i++;
} }
parameter.Push (0);
break;
case '>':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break; break;
case '\'': }
if (!insideString && !insideSingleLineComment && !insideMultiLineComment) { if (parameter.Count > 0) {
insideQuote = !insideQuote; parameter.Pop ();
} }
break; break;
case '"': case ',':
if (!insideQuote && !insideSingleLineComment && !insideMultiLineComment) { if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
insideString = !insideString; break;
}
if (parameter.Count > 0) {
parameter.Push (parameter.Pop () + 1);
} }
break; break;
case '/': case '/':
if (!insideQuote && !insideString && !insideMultiLineComment) { if (inString || inChar || inVerbatimString) {
if (document.GetCharAt (i) == '/') { break;
insideSingleLineComment = true;
} }
if (document.GetCharAt (i) == '*') { if (nextCh == '/') {
insideMultiLineComment = true; i++;
inSingleComment = true;
} }
if (nextCh == '*') {
inMultiLineComment = true;
} }
break; break;
case '*': case '*':
if (insideMultiLineComment && document.GetCharAt (i) == '/') { if (inString || inChar || inVerbatimString || inSingleComment) {
insideMultiLineComment = false; break;
}
if (nextCh == '/') {
i++;
inMultiLineComment = false;
}
break;
case '@':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (nextCh == '"') {
i++;
inVerbatimString = true;
} }
break; break;
case '\n': case '\n':
case '\r': case '\r':
insideSingleLineComment = false; inSingleComment = false;
inString = false;
inChar = false;
break; break;
case '{': case '\\':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { if (inString || inChar) {
bracket++; i++;
indexStack.Push (index);
} }
break; break;
case '}': case '"':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) { if (inSingleComment || inMultiLineComment || inChar) {
bracket--; break;
if (indexStack.Count > 0)
index = indexStack.Pop ();
} }
if (inVerbatimString) {
if (nextCh == '"') {
i++;
break; break;
case '(':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses++;
} }
inVerbatimString = false;
break; break;
case ')':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment) {
parentheses--;
} }
inString = !inString;
break;
case '\'':
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) {
break; break;
case ',':
if (!insideQuote && !insideString && !insideSingleLineComment && !insideMultiLineComment && parentheses == 1 && bracket == 0) {
index++;
} }
inChar = !inChar;
break; break;
} }
i++; }
} while (i <= cursor && parentheses >= 0); if (parameter.Count == 0 || bracketStack.Count > 0) {
Console.WriteLine (indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index); return -1;
return indexStack.Count >= 0 || parentheses != 1 || bracket > 0 ? -1 : index; }
return parameter.Pop() + 1;
} }
#region Context helper methods #region Context helper methods
@ -309,6 +351,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IsInString = false; IsInString = false;
IsInChar = false; IsInChar = false;
IsFistNonWs = true; IsFistNonWs = true;
IsInPreprocessorDirective = false;
break; break;
case '\\': case '\\':
if (IsInString || IsInChar) if (IsInString || IsInChar)
@ -340,6 +383,21 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
} }
protected bool IsInsideCommentStringOrDirective(int offset)
{
var lexer = new MiniLexer(document.Text);
lexer.Parse(0, offset);
return
lexer.IsInSingleComment ||
lexer.IsInString ||
lexer.IsInVerbatimString ||
lexer.IsInChar ||
lexer.IsInMultiLineComment ||
lexer.IsInPreprocessorDirective;
}
protected bool IsInsideCommentStringOrDirective() protected bool IsInsideCommentStringOrDirective()
{ {
var text = GetMemberTextToCaret(); var text = GetMemberTextToCaret();
@ -436,13 +494,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
state.CurrentMember = currentMember; state.CurrentMember = currentMember;
state.CurrentTypeDefinition = currentType; state.CurrentTypeDefinition = currentType;
state.CurrentUsingScope = CSharpParsedFile.GetUsingScope (location); state.CurrentUsingScope = CSharpUnresolvedFile.GetUsingScope (location);
if (state.CurrentMember != null) { if (state.CurrentMember != null) {
var node = Unit.GetNodeAt (location); var node = Unit.GetNodeAt (location);
if (node == null) if (node == null)
return state; return state;
var navigator = new NodeListResolveVisitorNavigator (new[] { node }); var navigator = new NodeListResolveVisitorNavigator (new[] { node });
var visitor = new ResolveVisitor (state, CSharpParsedFile, navigator); var visitor = new ResolveVisitor (state, CSharpUnresolvedFile, navigator);
Unit.AcceptVisitor (visitor, null); Unit.AcceptVisitor (visitor, null);
try { try {
var newState = visitor.GetResolverStateBefore (node); var newState = visitor.GetResolverStateBefore (node);
@ -597,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.Append (';'); wrapper.Append (';');
} }
protected CompilationUnit ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null) protected SyntaxTree ParseStub(string continuation, bool appendSemicolon = true, string afterContinuation = null)
{ {
var mt = GetMemberTextToCaret(); var mt = GetMemberTextToCaret();
if (mt == null) { if (mt == null) {
@ -623,52 +681,29 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (closingBrackets > 0) { if (closingBrackets > 0) {
wrapper.Append(new string('}', closingBrackets)); wrapper.Append(new string('}', closingBrackets));
} }
using (var stream = new System.IO.StringReader (wrapper.ToString ())) {
try {
var parser = new CSharpParser (); var parser = new CSharpParser ();
var result = parser.Parse(stream, "stub.cs", memberLocation.Line - 1 - generatedLines); foreach (var sym in CompletionContextProvider.ConditionalSymbols)
parser.CompilerSettings.ConditionalSymbols.Add (sym);
parser.InitialLocation = new TextLocation(memberLocation.Line - generatedLines, 1);
var result = parser.Parse(wrapper.ToString ());
return result; return result;
} catch (Exception) {
Console.WriteLine("------");
Console.WriteLine(wrapper);
throw;
}
}
} }
string cachedText = null; // string cachedText = null;
protected virtual void Reset () protected virtual void Reset ()
{ {
cachedText = null; // cachedText = null;
} }
protected Tuple<string, TextLocation> GetMemberTextToCaret() protected Tuple<string, TextLocation> GetMemberTextToCaret()
{ {
int startOffset; return CompletionContextProvider.GetMemberTextToCaret(offset, currentType, currentMember);
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
if (cachedText == null)
cachedText = document.GetText (startOffset, offset - startOffset);
return Tuple.Create (cachedText, document.GetLocation (startOffset));
} }
protected ExpressionResult GetInvocationBeforeCursor(bool afterBracket) protected ExpressionResult GetInvocationBeforeCursor(bool afterBracket)
{ {
CompilationUnit baseUnit; SyntaxTree baseUnit;
baseUnit = ParseStub("a", false); baseUnit = ParseStub("a", false);
var section = baseUnit.GetNodeAt<AttributeSection>(location.Line, location.Column - 2); var section = baseUnit.GetNodeAt<AttributeSection>(location.Line, location.Column - 2);
@ -723,10 +758,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public class ExpressionResult public class ExpressionResult
{ {
public AstNode Node { get; private set; } public AstNode Node { get; private set; }
public CompilationUnit Unit { get; private set; } public SyntaxTree Unit { get; private set; }
public ExpressionResult (AstNode item2, CompilationUnit item3) public ExpressionResult (AstNode item2, SyntaxTree item3)
{ {
this.Node = item2; this.Node = item2;
this.Unit = item3; this.Unit = item3;
@ -740,10 +775,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (ExpressionResult tuple) protected Tuple<ResolveResult, CSharpResolver> ResolveExpression (ExpressionResult tuple)
{ {
return ResolveExpression (tuple.Node, tuple.Unit); return ResolveExpression (tuple.Node);
} }
protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr, CompilationUnit unit) protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(AstNode expr)
{ {
if (expr == null) { if (expr == null) {
return null; return null;
@ -757,12 +792,13 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
resolveNode = expr; resolveNode = expr;
} }
try { try {
var ctx = CSharpParsedFile.GetResolver(Compilation, location); var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is SyntaxTree);
var root = expr.AncestorsAndSelf.FirstOrDefault(n => n is EntityDeclaration || n is CompilationUnit);
if (root == null) { if (root == null) {
return null; return null;
} }
var csResolver = new CSharpAstResolver (ctx, root, CSharpParsedFile); if (root is Accessor)
root = root.Parent;
var csResolver = CompletionContextProvider.GetResolver (GetState(), root);
var result = csResolver.Resolve(resolveNode); var result = csResolver.Resolve(resolveNode);
var state = csResolver.GetResolverStateBefore(resolveNode); var state = csResolver.GetResolverStateBefore(resolveNode);
return Tuple.Create(result, state); return Tuple.Create(result, state);
@ -773,128 +809,5 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
#endregion #endregion
class DefaultMemberProvider : IMemberProvider
{
CSharpCompletionEngineBase engine;
public DefaultMemberProvider (CSharpCompletionEngineBase engine)
{
this.engine = engine;
}
public void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = engine.location;
currentType = null;
foreach (var type in engine.CSharpParsedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
var document = engine.document;
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
}
} }
} }

184
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CSharpParameterCompletionEngine.cs

@ -1,4 +1,4 @@
// //
// CSharpParameterCompletionEngine.cs // CSharpParameterCompletionEngine.cs
// //
// Author: // Author:
@ -39,7 +39,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{ {
internal IParameterCompletionDataFactory factory; internal IParameterCompletionDataFactory factory;
public CSharpParameterCompletionEngine(IDocument document, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx, CompilationUnit unit, CSharpParsedFile parsedFile) : base (content, ctx, unit, parsedFile) public CSharpParameterCompletionEngine(IDocument document, ICompletionContextProvider completionContextProvider, IParameterCompletionDataFactory factory, IProjectContent content, CSharpTypeResolveContext ctx) : base (content, completionContextProvider, ctx)
{ {
if (document == null) { if (document == null) {
throw new ArgumentNullException("document"); throw new ArgumentNullException("document");
@ -53,13 +53,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetIndexerBeforeCursor() public ExpressionResult GetIndexerBeforeCursor()
{ {
CompilationUnit baseUnit; SyntaxTree baseUnit;
if (currentMember == null && currentType == null) { if (currentMember == null && currentType == null) {
return null; return null;
} }
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x] = a[1"); baseUnit = ParseStub("x] = a[1");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -76,13 +73,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetConstructorInitializerBeforeCursor() public ExpressionResult GetConstructorInitializerBeforeCursor()
{ {
CompilationUnit baseUnit; SyntaxTree baseUnit;
if (currentMember == null && currentType == null) { if (currentMember == null && currentType == null) {
return null; return null;
} }
if (Unit == null) {
return null;
}
baseUnit = ParseStub("a) {}", false); baseUnit = ParseStub("a) {}", false);
var expr = baseUnit.GetNodeAt <ConstructorInitializer>(location); var expr = baseUnit.GetNodeAt <ConstructorInitializer>(location);
@ -94,13 +88,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public ExpressionResult GetTypeBeforeCursor() public ExpressionResult GetTypeBeforeCursor()
{ {
CompilationUnit baseUnit; SyntaxTree baseUnit;
if (currentMember == null && currentType == null) { if (currentMember == null && currentType == null) {
return null; return null;
} }
if (Unit == null) {
return null;
}
baseUnit = ParseStub("x> a"); baseUnit = ParseStub("x> a");
//var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin; //var memberLocation = currentMember != null ? currentMember.Region.Begin : currentType.Region.Begin;
@ -113,25 +104,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
IEnumerable<IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult) IEnumerable<IMethod> CollectMethods(AstNode resolvedNode, MethodGroupResolveResult resolveResult)
{ {
// var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly); var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
bool onlyStatic = false; bool onlyStatic = false;
if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic) { if (resolvedNode is IdentifierExpression && currentMember != null && currentMember.IsStatic || resolveResult.TargetResult is TypeResolveResult) {
onlyStatic = true; onlyStatic = true;
} }
foreach (var method in resolveResult.Methods) { foreach (var method in resolveResult.Methods) {
if (method.IsConstructor) { if (method.IsConstructor) {
continue; continue;
} }
// if (!lookup.IsAccessible (member, true)) if (!lookup.IsAccessible (method, true))
// continue; continue;
if (onlyStatic && !method.IsStatic) { if (onlyStatic && !method.IsStatic) {
continue; continue;
} }
yield return method; yield return method;
} }
foreach (var extMethods in resolveResult.GetExtensionMethods ()) { foreach (var extMethods in resolveResult.GetEligibleExtensionMethods (true)) {
foreach (var method in extMethods) { foreach (var method in extMethods) {
yield return method; yield return method;
} }
@ -172,7 +162,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
} }
} }
if (invoke.Node is ObjectCreateExpression) { if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit); var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
if (createType.Item1.Type.Kind == TypeKind.Unknown) if (createType.Item1.Type.Kind == TypeKind.Unknown)
return null; return null;
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type); return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
@ -235,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0) if (GetCurrentParameterIndex(document.GetOffset(invoke.Node.StartLocation), offset) < 0)
return null; return null;
if (invoke.Node is ObjectCreateExpression) { if (invoke.Node is ObjectCreateExpression) {
var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type, invoke.Unit); var createType = ResolveExpression(((ObjectCreateExpression)invoke.Node).Type);
return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type); return factory.CreateConstructorProvider(document.GetOffset(invoke.Node.StartLocation), createType.Item1.Type);
} }
@ -317,17 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
List<string> GetUsedNamespaces() List<string> GetUsedNamespaces()
{ {
var scope = CSharpParsedFile.GetUsingScope(location); var scope = ctx.CurrentUsingScope;
var result = new List<string>(); var result = new List<string>();
var resolver = new CSharpResolver(ctx);
while (scope != null) { while (scope != null) {
result.Add(scope.NamespaceName); result.Add(scope.Namespace.FullName);
foreach (var u in scope.Usings) { foreach (var ns in scope.Usings) {
var ns = u.ResolveNamespace(resolver);
if (ns == null) {
continue;
}
result.Add(ns.FullName); result.Add(ns.FullName);
} }
scope = scope.Parent; scope = scope.Parent;
@ -335,144 +320,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return result; return result;
} }
public int GetCurrentParameterIndex(int triggerOffset, int endOffset)
{
char lastChar = document.GetCharAt(endOffset - 1);
if (lastChar == '(' || lastChar == '<') {
return 0;
}
var parameter = new Stack<int>();
var bracketStack = new Stack<Stack<int>>();
bool inSingleComment = false, inString = false, inVerbatimString = false, inChar = false, inMultiLineComment = false;
for (int i = triggerOffset; i < endOffset; i++) {
char ch = document.GetCharAt(i);
char nextCh = i + 1 < document.TextLength ? document.GetCharAt(i + 1) : '\0';
switch (ch) {
case '{':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
bracketStack.Push(parameter);
parameter = new Stack<int>();
break;
case '[':
case '(':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push(0);
break;
case '}':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (bracketStack.Count > 0) {
parameter = bracketStack.Pop();
} else {
return -1;
}
break;
case ']':
case ')':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop();
} else {
return -1;
}
break;
case '<':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
parameter.Push(0);
break;
case '>':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Pop();
}
break;
case ',':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (parameter.Count > 0) {
parameter.Push(parameter.Pop() + 1);
}
break;
case '/':
if (inString || inChar || inVerbatimString) {
break;
}
if (nextCh == '/') {
i++;
inSingleComment = true;
}
if (nextCh == '*') {
inMultiLineComment = true;
}
break;
case '*':
if (inString || inChar || inVerbatimString || inSingleComment) {
break;
}
if (nextCh == '/') {
i++;
inMultiLineComment = false;
}
break;
case '@':
if (inString || inChar || inVerbatimString || inSingleComment || inMultiLineComment) {
break;
}
if (nextCh == '"') {
i++;
inVerbatimString = true;
}
break;
case '\n':
case '\r':
inSingleComment = false;
inString = false;
inChar = false;
break;
case '\\':
if (inString || inChar) {
i++;
}
break;
case '"':
if (inSingleComment || inMultiLineComment || inChar) {
break;
}
if (inVerbatimString) {
if (nextCh == '"') {
i++;
break;
}
inVerbatimString = false;
break;
}
inString = !inString;
break;
case '\'':
if (inSingleComment || inMultiLineComment || inString || inVerbatimString) {
break;
}
inChar = !inChar;
break;
}
}
if (parameter.Count == 0 || bracketStack.Count > 0) {
return -1;
}
return parameter.Pop() + 1;
}
} }
} }

120
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs

@ -28,6 +28,7 @@ using System.Collections.Generic;
using ICSharpCode.NRefactory.Completion; using ICSharpCode.NRefactory.Completion;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Completion namespace ICSharpCode.NRefactory.CSharp.Completion
{ {
@ -58,6 +59,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
result.Add (data); result.Add (data);
} }
public void AddCustom (string displayText, string description = null, string completionText = null) public void AddCustom (string displayText, string description = null, string completionText = null)
{ {
result.Add (Factory.CreateLiteralCompletionData (displayText, description, completionText)); result.Add (Factory.CreateLiteralCompletionData (displayText, description, completionText));
@ -65,43 +67,66 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
HashSet<string> usedNamespaces = new HashSet<string> (); HashSet<string> usedNamespaces = new HashSet<string> ();
public void AddNamespace (string name) public void AddNamespace (INamespace ns)
{ {
if (string.IsNullOrEmpty (name) || usedNamespaces.Contains (name)) if (usedNamespaces.Contains (ns.Name))
return; return;
usedNamespaces.Add (name); usedNamespaces.Add (ns.Name);
result.Add (Factory.CreateNamespaceCompletionData (name)); result.Add (Factory.CreateNamespaceCompletionData (ns));
} }
HashSet<string> usedTypes = new HashSet<string> (); public void AddAlias(string alias)
public void AddType (IType type, string shortType)
{ {
if (type == null || string.IsNullOrEmpty (shortType) || usedTypes.Contains (shortType)) result.Add (Factory.CreateLiteralCompletionData (alias));
return;
usedTypes.Add (shortType);
result.Add (Factory.CreateTypeCompletionData (type, shortType));
} }
public void AddType (IUnresolvedTypeDefinition type, string shortType)
HashSet<string> usedTypes = new HashSet<string> ();
public ICompletionData AddType(IType type, string shortType)
{ {
if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType)) if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType))
return; return null;
if (type.Name == "Void" && type.Namespace == "System")
return null;
var def = type.GetDefinition ();
if (def != null && def.ParentAssembly != completion.ctx.CurrentAssembly && !def.IsBrowsable ())
return null;
usedTypes.Add(shortType); usedTypes.Add(shortType);
result.Add (Factory.CreateTypeCompletionData (type, shortType)); var iCompletionData = Factory.CreateTypeCompletionData(type, shortType);
result.Add(iCompletionData);
return iCompletionData;
} }
Dictionary<string, List<ICompletionData>> data = new Dictionary<string, List<ICompletionData>> (); Dictionary<string, List<ICompletionData>> data = new Dictionary<string, List<ICompletionData>> ();
public void AddVariable (IVariable variable) public ICompletionData AddVariable(IVariable variable)
{ {
if (data.ContainsKey(variable.Name)) if (data.ContainsKey(variable.Name))
return; return null;
data [variable.Name] = new List<ICompletionData>(); data [variable.Name] = new List<ICompletionData>();
result.Add (Factory.CreateVariableCompletionData (variable)); var cd = Factory.CreateVariableCompletionData(variable);
result.Add(cd);
return cd;
}
public ICompletionData AddNamedParameterVariable(IVariable variable)
{
var name = variable.Name + ":";
if (data.ContainsKey(name))
return null;
data [name] = new List<ICompletionData>();
var cd = Factory.CreateVariableCompletionData(variable);
cd.CompletionText += ":";
cd.DisplayText += ":";
result.Add(cd);
return cd;
} }
public void AddTypeParameter (IUnresolvedTypeParameter variable) public void AddTypeParameter (ITypeParameter variable)
{ {
if (data.ContainsKey (variable.Name)) if (data.ContainsKey (variable.Name))
return; return;
@ -109,51 +134,17 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
result.Add (Factory.CreateVariableCompletionData (variable)); result.Add (Factory.CreateVariableCompletionData (variable));
} }
public ICompletionData AddMember (IUnresolvedMember member) public ICompletionData AddMember (IMember member)
{ {
var newData = Factory.CreateEntityCompletionData (member); var newData = Factory.CreateEntityCompletionData (member);
// newData.HideExtensionParameter = HideExtensionParameter; if (member.ParentAssembly != completion.ctx.CurrentAssembly && !member.IsBrowsable ())
string memberKey = newData.DisplayText;
if (memberKey == null)
return null; return null;
if (member is IMember) {
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition.Resolve (completion.ctx));
}
List<ICompletionData> 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<ICompletionData> ();
data [memberKey].Add (newData);
}
return newData;
}
public ICompletionData AddMember (IMember member)
{
var newData = Factory.CreateEntityCompletionData (member);
// newData.HideExtensionParameter = HideExtensionParameter;
string memberKey = newData.DisplayText; string memberKey = newData.DisplayText;
if (memberKey == null) if (memberKey == null)
return null; return null;
if (member is IMember) { if (member is IMember) {
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition); newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition);
} }
@ -219,6 +210,25 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return 1; return 1;
} }
} }
HashSet<IType> addedEnums = new HashSet<IType> ();
public void AddEnumMembers (IType resolvedType, CSharpResolver state, string typeString)
{
if (addedEnums.Contains (resolvedType))
return;
addedEnums.Add (resolvedType);
if (typeString.Contains(".")) {
AddType(resolvedType, typeString);
}
foreach (var field in resolvedType.GetFields ()) {
if (field.IsPublic && (field.IsConst || field.IsStatic)) {
Result.Add(Factory.CreateEntityCompletionData(
field,
typeString + "." + field.Name
)
);
}
}
}
} }
} }

213
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionContextProvider.cs

@ -0,0 +1,213 @@
//
// IMemberProvider.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc.
//
// 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;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.CSharp.TypeSystem;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface ICompletionContextProvider
{
IList<string> ConditionalSymbols {
get;
}
void GetCurrentMembers (int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember);
Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember);
CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode);
}
public class DefaultCompletionContextProvider : ICompletionContextProvider
{
readonly IDocument document;
readonly CSharpUnresolvedFile unresolvedFile;
readonly List<string> symbols = new List<string> ();
public IList<string> ConditionalSymbols {
get {
return symbols;
}
}
public DefaultCompletionContextProvider (IDocument document, CSharpUnresolvedFile unresolvedFile)
{
if (document == null)
throw new ArgumentNullException("document");
if (unresolvedFile == null)
throw new ArgumentNullException("unresolvedFile");
this.document = document;
this.unresolvedFile = unresolvedFile;
}
public void AddSymbol (string sym)
{
symbols.Add (sym);
}
public void GetCurrentMembers(int offset, out IUnresolvedTypeDefinition currentType, out IUnresolvedMember currentMember)
{
//var document = engine.document;
var location = document.GetLocation(offset);
currentType = null;
foreach (var type in unresolvedFile.TopLevelTypeDefinitions) {
if (type.Region.Begin < location)
currentType = type;
}
currentType = FindInnerType (currentType, location);
// location is beyond last reported end region, now we need to check, if the end region changed
if (currentType != null && currentType.Region.End < location) {
if (!IsInsideType (currentType, location))
currentType = null;
}
currentMember = null;
if (currentType != null) {
foreach (var member in currentType.Members) {
if (member.Region.Begin < location && (currentMember == null || currentMember.Region.Begin < member.Region.Begin))
currentMember = member;
}
}
// location is beyond last reported end region, now we need to check, if the end region changed
// NOTE: Enums are a special case, there the "last" field needs to be treated as current member
if (currentMember != null && currentMember.Region.End < location && currentType.Kind != TypeKind.Enum) {
if (!IsInsideType (currentMember, location))
currentMember = null;
}/*
var stack = GetBracketStack (engine.GetMemberTextToCaret ().Item1);
if (stack.Count == 0)
currentMember = null;*/
}
IUnresolvedTypeDefinition FindInnerType (IUnresolvedTypeDefinition parent, TextLocation location)
{
if (parent == null)
return null;
var currentType = parent;
foreach (var type in parent.NestedTypes) {
if (type.Region.Begin < location && location < type.Region.End)
currentType = FindInnerType (type, location);
}
return currentType;
}
bool IsInsideType (IUnresolvedEntity currentType, TextLocation location)
{
int startOffset = document.GetOffset (currentType.Region.Begin);
int endOffset = document.GetOffset (location);
//bool foundEndBracket = false;
var bracketStack = new Stack<char> ();
bool isInString = false, isInChar = false;
bool isInLineComment = false, isInBlockComment = false;
for (int i = startOffset; i < endOffset; i++) {
char ch = document.GetCharAt (i);
switch (ch) {
case '(':
case '[':
case '{':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
bracketStack.Push (ch);
break;
case ')':
case ']':
case '}':
if (!isInString && !isInChar && !isInLineComment && !isInBlockComment)
if (bracketStack.Count > 0)
bracketStack.Pop ();
break;
case '\r':
case '\n':
isInLineComment = false;
break;
case '/':
if (isInBlockComment) {
if (i > 0 && document.GetCharAt (i - 1) == '*')
isInBlockComment = false;
} else if (!isInString && !isInChar && i + 1 < document.TextLength) {
char nextChar = document.GetCharAt (i + 1);
if (nextChar == '/')
isInLineComment = true;
if (!isInLineComment && nextChar == '*')
isInBlockComment = true;
}
break;
case '"':
if (!(isInChar || isInLineComment || isInBlockComment))
isInString = !isInString;
break;
case '\'':
if (!(isInString || isInLineComment || isInBlockComment))
isInChar = !isInChar;
break;
default :
break;
}
}
return bracketStack.Any (t => t == '{');
}
public Tuple<string, TextLocation> GetMemberTextToCaret(int caretOffset, IUnresolvedTypeDefinition currentType, IUnresolvedMember currentMember)
{
int startOffset;
if (currentMember != null && currentType != null && currentType.Kind != TypeKind.Enum) {
startOffset = document.GetOffset(currentMember.Region.Begin);
} else if (currentType != null) {
startOffset = document.GetOffset(currentType.Region.Begin);
} else {
startOffset = 0;
}
while (startOffset > 0) {
char ch = document.GetCharAt(startOffset - 1);
if (ch != ' ' && ch != '\t') {
break;
}
--startOffset;
}
return Tuple.Create (document.GetText (startOffset, caretOffset - startOffset), document.GetLocation (startOffset));
}
public CSharpAstResolver GetResolver (CSharpResolver resolver, AstNode rootNode)
{
return new CSharpAstResolver (resolver, rootNode, unresolvedFile);
}
}
}

7
NRefactory/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs

@ -32,13 +32,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{ {
public interface ICompletionDataFactory public interface ICompletionDataFactory
{ {
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity);
ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity, string text);
ICompletionData CreateEntityCompletionData (IEntity entity); ICompletionData CreateEntityCompletionData (IEntity entity);
ICompletionData CreateEntityCompletionData (IEntity entity, string text); ICompletionData CreateEntityCompletionData (IEntity entity, string text);
ICompletionData CreateTypeCompletionData (IType type, string shortType); ICompletionData CreateTypeCompletionData (IType type, string shortType);
ICompletionData CreateTypeCompletionData (IUnresolvedTypeDefinition type, string shortType);
/// <summary> /// <summary>
/// Creates a generic completion data. /// Creates a generic completion data.
@ -54,11 +51,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
/// </param> /// </param>
ICompletionData CreateLiteralCompletionData (string title, string description = null, string insertText = null); ICompletionData CreateLiteralCompletionData (string title, string description = null, string insertText = null);
ICompletionData CreateNamespaceCompletionData (string name); ICompletionData CreateNamespaceCompletionData (INamespace name);
ICompletionData CreateVariableCompletionData (IVariable variable); 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); ICompletionData CreateEventCreationCompletionData (string varName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType);

387
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

@ -1,4 +1,4 @@
// //
// AstFormattingVisitor.cs // AstFormattingVisitor.cs
// //
// Author: // Author:
@ -98,6 +98,11 @@ namespace ICSharpCode.NRefactory.CSharp
set; set;
} }
public DomRegion FormattingRegion {
get;
set;
}
public AstFormattingVisitor(CSharpFormattingOptions policy, IDocument document, TextEditorOptions options = null) public AstFormattingVisitor(CSharpFormattingOptions policy, IDocument document, TextEditorOptions options = null)
{ {
if (policy == null) { if (policy == null) {
@ -112,6 +117,22 @@ namespace ICSharpCode.NRefactory.CSharp
curIndent = new Indent(this.options); curIndent = new Indent(this.options);
} }
protected override void VisitChildren (AstNode node)
{
if (!FormattingRegion.IsEmpty) {
if (node.EndLocation < FormattingRegion.Begin || node.StartLocation > FormattingRegion.End)
return;
}
AstNode next;
for (var child = node.FirstChild; child != null; child = next) {
// Store next to allow the loop to continue
// if the visitor removes/replaces child.
next = child.NextSibling;
child.AcceptVisitor (this);
}
}
/// <summary> /// <summary>
/// Applies the changes to the input document. /// Applies the changes to the input document.
/// </summary> /// </summary>
@ -152,10 +173,10 @@ namespace ICSharpCode.NRefactory.CSharp
} }
if (change.Offset < previousChange.Offset + previousChange.RemovalLength) { if (change.Offset < previousChange.Offset + previousChange.RemovalLength) {
#if DEBUG #if DEBUG
Console.WriteLine ("change 1:" + change); Console.WriteLine ("change 1:" + change + " at " + document.GetLocation (change.Offset));
Console.WriteLine (change.StackTrace); Console.WriteLine (change.StackTrace);
Console.WriteLine ("change 2:" + change); Console.WriteLine ("change 2:" + previousChange + " at " + document.GetLocation (previousChange.Offset));
Console.WriteLine (previousChange.StackTrace); Console.WriteLine (previousChange.StackTrace);
#endif #endif
throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange); throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange);
@ -178,9 +199,9 @@ namespace ICSharpCode.NRefactory.CSharp
changes.Clear(); changes.Clear();
} }
public override void VisitCompilationUnit(CompilationUnit unit) public override void VisitSyntaxTree(SyntaxTree unit)
{ {
base.VisitCompilationUnit(unit); base.VisitSyntaxTree(unit);
} }
public void EnsureBlankLinesAfter(AstNode node, int blankLines) public void EnsureBlankLinesAfter(AstNode node, int blankLines)
@ -228,26 +249,32 @@ namespace ICSharpCode.NRefactory.CSharp
for (int i = 0; i < blankLines; i++) { for (int i = 0; i < blankLines; i++) {
sb.Append(this.options.EolMarker); sb.Append(this.options.EolMarker);
} }
if (end - start == 0 && sb.Length == 0)
return;
AddChange(start, end - start, sb.ToString()); AddChange(start, end - start, sb.ToString());
} }
public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration) public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
{ {
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) { if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings); EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
} } else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) { FixIndentationForceNewLine(usingDeclaration.StartLocation);
EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings); EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
} else {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
} }
} }
public override void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration) public override void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
{ {
if (!(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) { if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings); EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
} } else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) {
if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling is UsingAliasDeclaration)) { FixIndentationForceNewLine(usingDeclaration.StartLocation);
EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings); EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
} else {
FixIndentationForceNewLine(usingDeclaration.StartLocation);
} }
} }
@ -445,7 +472,7 @@ namespace ICSharpCode.NRefactory.CSharp
return i; return i;
} }
int ForceSpacesBeforeRemoveNewLines(AstNode n) int ForceSpacesBeforeRemoveNewLines(AstNode n, bool forceSpace = true)
{ {
if (n == null || n.IsNull) { if (n == null || n.IsNull) {
return 0; return 0;
@ -459,7 +486,7 @@ namespace ICSharpCode.NRefactory.CSharp
i--; i--;
} }
var length = System.Math.Max(0, (offset - 1) - i); var length = System.Math.Max(0, (offset - 1) - i);
AddChange(i + 1, length, " "); AddChange(i + 1, length, forceSpace ? " " : "");
return i; return i;
} }
@ -470,12 +497,22 @@ namespace ICSharpCode.NRefactory.CSharp
switch (policy.PropertyFormatting) { switch (policy.PropertyFormatting) {
case PropertyFormatting.AllowOneLine: case PropertyFormatting.AllowOneLine:
bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter); bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter);
if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != propertyDeclaration.RBraceToken.StartLocation.Line) { int accessorLine = propertyDeclaration.RBraceToken.StartLocation.Line;
if (!propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull) {
accessorLine = propertyDeclaration.Getter.StartLocation.Line;
} else if (propertyDeclaration.Getter.IsNull && !propertyDeclaration.Setter.IsNull) {
accessorLine = propertyDeclaration.Setter.StartLocation.Line;
} else {
var acc = propertyDeclaration.Getter.StartLocation < propertyDeclaration.Setter.StartLocation ?
propertyDeclaration.Getter : propertyDeclaration.Setter;
accessorLine = acc.StartLocation.Line;
}
if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != accessorLine) {
EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken); EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
} else { } else {
ForceSpacesBefore(propertyDeclaration.Getter, true); ForceSpacesBefore(propertyDeclaration.Getter, true);
ForceSpacesBefore(propertyDeclaration.Setter, true); ForceSpacesBefore(propertyDeclaration.Setter, true);
ForceSpacesBefore(propertyDeclaration.RBraceToken, true); ForceSpacesBeforeRemoveNewLines(propertyDeclaration.RBraceToken, true);
oneLine = true; oneLine = true;
} }
break; break;
@ -574,10 +611,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket); ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket);
ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket); ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket);
ForceSpacesBefore(indexerDeclaration.RBracketToken, policy.SpaceWithinIndexerDeclarationBracket);
FormatCommas(indexerDeclaration, policy.SpaceBeforeIndexerDeclarationParameterComma, policy.SpaceAfterIndexerDeclarationParameterComma);
FormatParameters(indexerDeclaration);
FormatAttributedNode(indexerDeclaration); FormatAttributedNode(indexerDeclaration);
EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken); EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken);
@ -786,6 +821,119 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
void FormatParameters(AstNode node)
{
Wrapping methodCallArgumentWrapping;
bool newLineAferMethodCallOpenParentheses;
bool methodClosingParenthesesOnNewLine;
bool spaceWithinMethodCallParentheses;
bool spaceAfterMethodCallParameterComma;
bool spaceBeforeMethodCallParameterComma;
CSharpTokenNode rParToken;
AstNodeCollection<ParameterDeclaration> parameters;
var constructorDeclaration = node as ConstructorDeclaration;
if (constructorDeclaration != null) {
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinConstructorDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterConstructorDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeConstructorDeclarationParameterComma;
rParToken = constructorDeclaration.RParToken;
parameters = constructorDeclaration.Parameters;
} else if (node is IndexerDeclaration) {
var indexer = (IndexerDeclaration)node;
methodCallArgumentWrapping = policy.IndexerDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerDeclarationOpenBracket;
methodClosingParenthesesOnNewLine = policy.IndexerDeclarationClosingBracketOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinIndexerDeclarationBracket;
spaceAfterMethodCallParameterComma = policy.SpaceAfterIndexerDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeIndexerDeclarationParameterComma;
rParToken = indexer.RBracketToken;
parameters = indexer.Parameters;
} else if (node is OperatorDeclaration) {
var op = (OperatorDeclaration)node;
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
rParToken = op.RParToken;
parameters = op.Parameters;
} else {
var methodDeclaration = node as MethodDeclaration;
methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
rParToken = methodDeclaration.RParToken;
parameters = methodDeclaration.Parameters;
}
if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
methodCallArgumentWrapping = Wrapping.DoNotChange;
bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, parameters.Count);
if (wrapMethodCall && parameters.Any()) {
if (newLineAferMethodCallOpenParentheses) {
curIndent.Push(IndentType.Continuation);
foreach (var arg in parameters) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.Pop();
} else {
int extraSpaces = parameters.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
curIndent.ExtraSpaces += extraSpaces;
foreach (var arg in parameters.Skip(1)) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.ExtraSpaces -= extraSpaces;
}
if (!rParToken.IsNull) {
if (methodClosingParenthesesOnNewLine) {
FixStatementIndentation(rParToken.StartLocation);
} else {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
}
}
} else {
foreach (var arg in parameters) {
if (arg.PrevSibling != null) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
} else {
ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
}
}
arg.AcceptVisitor(this);
}
if (!rParToken.IsNull) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
bool sameLine = rParToken.GetPrevNode().StartLocation.Line == rParToken.StartLocation.Line;
if (sameLine) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
FixStatementIndentation(rParToken.StartLocation);
}
}
}
}
if (!rParToken.IsNull) {
foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
}
}
}
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{ {
FormatAttributedNode(methodDeclaration); FormatAttributedNode(methodDeclaration);
@ -793,12 +941,11 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (methodDeclaration.Parameters.Any()) { if (methodDeclaration.Parameters.Any()) {
ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceWithinMethodDeclarationParentheses); FormatParameters(methodDeclaration);
} else { } else {
ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
} }
FormatCommas(methodDeclaration, policy.SpaceBeforeMethodDeclarationParameterComma, policy.SpaceAfterMethodDeclarationParameterComma);
if (!methodDeclaration.Body.IsNull) { if (!methodDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken, methodDeclaration.Body.RBraceToken); EnforceBraceStyle(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken, methodDeclaration.Body.RBraceToken);
@ -816,12 +963,11 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses); ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (operatorDeclaration.Parameters.Any()) { if (operatorDeclaration.Parameters.Any()) {
ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses); ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceWithinMethodDeclarationParentheses); FormatParameters(operatorDeclaration);
} else { } else {
ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
} }
FormatCommas(operatorDeclaration, policy.SpaceBeforeMethodDeclarationParameterComma, policy.SpaceAfterMethodDeclarationParameterComma);
if (!operatorDeclaration.Body.IsNull) { if (!operatorDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken, operatorDeclaration.Body.RBraceToken); EnforceBraceStyle(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken, operatorDeclaration.Body.RBraceToken);
@ -839,12 +985,11 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses); ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses);
if (constructorDeclaration.Parameters.Any()) { if (constructorDeclaration.Parameters.Any()) {
ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses); ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses);
ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceWithinConstructorDeclarationParentheses); FormatParameters(constructorDeclaration);
} else { } else {
ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses); ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
} }
FormatCommas(constructorDeclaration, policy.SpaceBeforeConstructorDeclarationParameterComma, policy.SpaceAfterConstructorDeclarationParameterComma);
if (!constructorDeclaration.Body.IsNull) { if (!constructorDeclaration.Body.IsNull) {
EnforceBraceStyle(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken); EnforceBraceStyle(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken);
@ -1174,6 +1319,8 @@ namespace ICSharpCode.NRefactory.CSharp
TextReplaceAction AddChange(int offset, int removedChars, string insertedText) TextReplaceAction AddChange(int offset, int removedChars, string insertedText)
{ {
if (removedChars == 0 && string.IsNullOrEmpty (insertedText))
return null;
var action = new TextReplaceAction (offset, removedChars, insertedText); var action = new TextReplaceAction (offset, removedChars, insertedText);
changes.Add(action); changes.Add(action);
return action; return action;
@ -1283,11 +1430,14 @@ namespace ICSharpCode.NRefactory.CSharp
} }
if (!ifElseStatement.FalseStatement.IsNull) { if (!ifElseStatement.FalseStatement.IsNull) {
PlaceOnNewLine(policy.PlaceElseOnNewLine || !(ifElseStatement.TrueStatement is BlockStatement) && policy.IfElseBraceForcement != BraceForcement.AddBraces, ifElseStatement.ElseToken); var placeElseOnNewLine = policy.ElseNewLinePlacement;
if (!(ifElseStatement.TrueStatement is BlockStatement) && policy.IfElseBraceForcement != BraceForcement.AddBraces)
placeElseOnNewLine = NewLinePlacement.NewLine;
PlaceOnNewLine(placeElseOnNewLine, ifElseStatement.ElseToken);
var forcement = policy.IfElseBraceForcement; var forcement = policy.IfElseBraceForcement;
if (ifElseStatement.FalseStatement is IfElseStatement) { if (ifElseStatement.FalseStatement is IfElseStatement) {
forcement = BraceForcement.DoNotChange; forcement = BraceForcement.DoNotChange;
PlaceOnNewLine(policy.PlaceElseIfOnNewLine, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken); PlaceOnNewLine(policy.ElseIfNewLinePlacement, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken);
} }
FixEmbeddedStatment(policy.StatementBraceStyle, forcement, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement); FixEmbeddedStatment(policy.StatementBraceStyle, forcement, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement);
} }
@ -1378,7 +1528,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
foreach (CatchClause clause in tryCatchStatement.CatchClauses) { foreach (CatchClause clause in tryCatchStatement.CatchClauses) {
PlaceOnNewLine(policy.PlaceCatchOnNewLine, clause.CatchToken); PlaceOnNewLine(policy.CatchNewLinePlacement, clause.CatchToken);
if (!clause.LParToken.IsNull) { if (!clause.LParToken.IsNull) {
ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses); ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses);
@ -1389,7 +1539,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
if (!tryCatchStatement.FinallyBlock.IsNull) { if (!tryCatchStatement.FinallyBlock.IsNull) {
PlaceOnNewLine(policy.PlaceFinallyOnNewLine, tryCatchStatement.FinallyToken); PlaceOnNewLine(policy.FinallyNewLinePlacement, tryCatchStatement.FinallyToken);
FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock); FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock);
} }
@ -1443,7 +1593,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement) public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
{ {
PlaceOnNewLine(policy.PlaceWhileOnNewLine, doWhileStatement.WhileToken); PlaceOnNewLine(policy.WhileNewLinePlacement, doWhileStatement.WhileToken);
FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, doWhileStatement.EmbeddedStatement); FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, doWhileStatement.EmbeddedStatement);
} }
@ -1495,6 +1645,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
if (!anonymousMethodExpression.Body.IsNull) { if (!anonymousMethodExpression.Body.IsNull) {
EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken); EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken);
VisitBlockWithoutFixingBraces(anonymousMethodExpression.Body, policy.IndentBlocks);
return;
} }
base.VisitAnonymousMethodExpression(anonymousMethodExpression); base.VisitAnonymousMethodExpression(anonymousMethodExpression);
} }
@ -1600,29 +1752,156 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
bool DoWrap (Wrapping wrapping, AstNode wrapNode, int argumentCount)
{
return wrapping == Wrapping.WrapAlways ||
options.WrapLineLength > 0 && argumentCount > 1 && wrapping == Wrapping.WrapIfTooLong && wrapNode.StartLocation.Column >= options.WrapLineLength;
}
void FormatArguments(AstNode node)
{
Wrapping methodCallArgumentWrapping;
bool newLineAferMethodCallOpenParentheses;
bool methodClosingParenthesesOnNewLine;
bool spaceWithinMethodCallParentheses;
bool spaceAfterMethodCallParameterComma;
bool spaceBeforeMethodCallParameterComma;
CSharpTokenNode rParToken;
AstNodeCollection<Expression> arguments;
var indexer = node as IndexerExpression;
if (indexer != null) {
methodCallArgumentWrapping = policy.IndexerArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerOpenBracket;
methodClosingParenthesesOnNewLine = policy.IndexerClosingBracketOnNewLine;
spaceWithinMethodCallParentheses = policy.SpacesWithinBrackets;
spaceAfterMethodCallParameterComma = policy.SpaceAfterBracketComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeBracketComma;
rParToken = indexer.RBracketToken;
arguments = indexer.Arguments;
} else if (node is ObjectCreateExpression) {
var oce = node as ObjectCreateExpression;
methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma;
rParToken = oce.RParToken;
arguments = oce.Arguments;
} else {
InvocationExpression invocationExpression = node as InvocationExpression;
methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
spaceWithinMethodCallParentheses = policy.SpaceWithinMethodCallParentheses;
spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodCallParameterComma;
spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodCallParameterComma;
rParToken = invocationExpression.RParToken;
arguments = invocationExpression.Arguments;
}
if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
methodCallArgumentWrapping = Wrapping.DoNotChange;
bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, arguments.Count);
if (wrapMethodCall && arguments.Any()) {
if (newLineAferMethodCallOpenParentheses) {
curIndent.Push(IndentType.Continuation);
foreach (var arg in arguments) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.Pop();
} else {
int extraSpaces = arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
curIndent.ExtraSpaces += extraSpaces;
foreach (var arg in arguments.Skip(1)) {
FixStatementIndentation(arg.StartLocation);
}
curIndent.ExtraSpaces -= extraSpaces;
}
if (!rParToken.IsNull) {
if (methodClosingParenthesesOnNewLine) {
FixStatementIndentation(rParToken.StartLocation);
} else {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
}
}
} else {
foreach (var arg in arguments) {
if (arg.PrevSibling != null) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
} else {
ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
}
}
arg.AcceptVisitor(this);
}
if (!rParToken.IsNull) {
if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
bool sameLine = rParToken.GetPrevNode().EndLocation.Line == rParToken.StartLocation.Line;
if (sameLine) {
ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
} else {
FixStatementIndentation(rParToken.StartLocation);
}
}
}
}
if (!rParToken.IsNull) {
foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
}
}
}
public override void VisitInvocationExpression(InvocationExpression invocationExpression) public override void VisitInvocationExpression(InvocationExpression invocationExpression)
{ {
ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses); ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses);
if (invocationExpression.Arguments.Any()) { if (invocationExpression.Arguments.Any()) {
ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses); ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses);
ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceWithinMethodCallParentheses);
} else { } else {
ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
} }
FormatCommas(invocationExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma);
base.VisitInvocationExpression(invocationExpression); if (!invocationExpression.Target.IsNull)
invocationExpression.Target.AcceptVisitor(this);
if (invocationExpression.Target is MemberReferenceExpression) {
var mt = (MemberReferenceExpression)invocationExpression.Target;
if (mt.Target is InvocationExpression) {
if (DoWrap(policy.ChainedMethodCallWrapping, mt.DotToken, 2)) {
curIndent.Push(IndentType.Continuation);
FixStatementIndentation(mt.DotToken.StartLocation);
curIndent.Pop();
} else {
if (policy.ChainedMethodCallWrapping == Wrapping.DoNotWrap)
ForceSpacesBeforeRemoveNewLines(mt.DotToken, false);
}
}
}
FormatArguments(invocationExpression);
} }
public override void VisitIndexerExpression(IndexerExpression indexerExpression) public override void VisitIndexerExpression(IndexerExpression indexerExpression)
{ {
ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets); ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets);
ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets); ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets);
ForceSpacesBefore(indexerExpression.RBracketToken, policy.SpacesWithinBrackets);
FormatCommas(indexerExpression, policy.SpaceBeforeBracketComma, policy.SpaceAfterBracketComma);
base.VisitIndexerExpression(indexerExpression); if (!indexerExpression.Target.IsNull)
indexerExpression.Target.AcceptVisitor(this);
FormatArguments(indexerExpression);
} }
public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
@ -1667,23 +1946,18 @@ namespace ICSharpCode.NRefactory.CSharp
ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses); ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses);
if (objectCreateExpression.Arguments.Any()) { if (objectCreateExpression.Arguments.Any()) {
if (!objectCreateExpression.LParToken.IsNull) { if (!objectCreateExpression.LParToken.IsNull)
ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses); ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses);
}
if (!objectCreateExpression.RParToken.IsNull) {
ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesWithinNewParentheses);
}
} else { } else {
if (!objectCreateExpression.LParToken.IsNull) { if (!objectCreateExpression.LParToken.IsNull)
ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses); ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses);
} }
if (!objectCreateExpression.RParToken.IsNull) {
ForceSpacesBefore(objectCreateExpression.RParToken, policy.SpacesBetweenEmptyNewParentheses);
}
}
FormatCommas(objectCreateExpression, policy.SpaceBeforeNewParameterComma, policy.SpaceAfterNewParameterComma);
base.VisitObjectCreateExpression(objectCreateExpression); if (!objectCreateExpression.Type.IsNull)
objectCreateExpression.Type.AcceptVisitor(this);
FormatArguments(objectCreateExpression);
} }
public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression) public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression)
@ -1694,7 +1968,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression) public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
{ {
if (policy.ArrayInitializerWrapping == Wrapping.WrapAlways) { if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) {
EnforceBraceStyle(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken, arrayInitializerExpression.RBraceToken); EnforceBraceStyle(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken, arrayInitializerExpression.RBraceToken);
curIndent.Push(IndentType.Block); curIndent.Push(IndentType.Block);
foreach (var init in arrayInitializerExpression.Elements) { foreach (var init in arrayInitializerExpression.Elements) {
@ -1728,6 +2002,12 @@ namespace ICSharpCode.NRefactory.CSharp
base.VisitNamedArgumentExpression(namedArgumentExpression); base.VisitNamedArgumentExpression(namedArgumentExpression);
} }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
{
ForceSpacesAfter(memberReferenceExpression.DotToken, false);
base.VisitMemberReferenceExpression(memberReferenceExpression);
}
#endregion #endregion
void ForceSpaceBefore(int offset, bool forceSpace) void ForceSpaceBefore(int offset, bool forceSpace)
@ -1804,15 +2084,20 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
void PlaceOnNewLine(bool newLine, AstNode keywordNode) void PlaceOnNewLine(NewLinePlacement newLine, AstNode keywordNode)
{ {
if (keywordNode == null) { if (keywordNode == null || newLine == NewLinePlacement.DoNotCare) {
return; return;
} }
var prev = keywordNode.GetPrevNode ();
if (prev is Comment || prev is PreProcessorDirective)
return;
int offset = document.GetOffset(keywordNode.StartLocation); int offset = document.GetOffset(keywordNode.StartLocation);
int whitespaceStart = SearchWhitespaceStart(offset); int whitespaceStart = SearchWhitespaceStart(offset);
string indentString = newLine ? this.options.EolMarker + this.curIndent.IndentString : " "; string indentString = newLine == NewLinePlacement.NewLine ? this.options.EolMarker + this.curIndent.IndentString : " ";
AddChange(whitespaceStart, offset - whitespaceStart, indentString); AddChange(whitespaceStart, offset - whitespaceStart, indentString);
} }

81
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/CSharpFormattingOptions.cs

@ -56,11 +56,18 @@ namespace ICSharpCode.NRefactory.CSharp
} }
public enum Wrapping { public enum Wrapping {
DoNotChange,
DoNotWrap, DoNotWrap,
WrapAlways, WrapAlways,
WrapIfTooLong WrapIfTooLong
} }
public enum NewLinePlacement {
DoNotCare,
NewLine,
SameLine
}
public class CSharpFormattingOptions public class CSharpFormattingOptions
{ {
public string Name { public string Name {
@ -298,27 +305,27 @@ namespace ICSharpCode.NRefactory.CSharp
#endregion #endregion
#region NewLines #region NewLines
public bool PlaceElseOnNewLine { // tested public NewLinePlacement ElseNewLinePlacement { // tested
get; get;
set; set;
} }
public bool PlaceElseIfOnNewLine { // tested public NewLinePlacement ElseIfNewLinePlacement { // tested
get; get;
set; set;
} }
public bool PlaceCatchOnNewLine { // tested public NewLinePlacement CatchNewLinePlacement { // tested
get; get;
set; set;
} }
public bool PlaceFinallyOnNewLine { // tested public NewLinePlacement FinallyNewLinePlacement { // tested
get; get;
set; set;
} }
public bool PlaceWhileOnNewLine { // tested public NewLinePlacement WhileNewLinePlacement { // tested
get; get;
set; set;
} }
@ -786,6 +793,70 @@ namespace ICSharpCode.NRefactory.CSharp
set; set;
} }
public Wrapping ChainedMethodCallWrapping {
get;
set;
}
public Wrapping MethodCallArgumentWrapping {
get;
set;
}
public bool NewLineAferMethodCallOpenParentheses {
get;
set;
}
public bool MethodCallClosingParenthesesOnNewLine {
get;
set;
}
public Wrapping IndexerArgumentWrapping {
get;
set;
}
public bool NewLineAferIndexerOpenBracket {
get;
set;
}
public bool IndexerClosingBracketOnNewLine {
get;
set;
}
public Wrapping MethodDeclarationParameterWrapping {
get;
set;
}
public bool NewLineAferMethodDeclarationOpenParentheses {
get;
set;
}
public bool MethodDeclarationClosingParenthesesOnNewLine {
get;
set;
}
public Wrapping IndexerDeclarationParameterWrapping {
get;
set;
}
public bool NewLineAferIndexerDeclarationOpenBracket {
get;
set;
}
public bool IndexerDeclarationClosingBracketOnNewLine {
get;
set;
}
#endregion #endregion
internal CSharpFormattingOptions() internal CSharpFormattingOptions()

132
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/FormattingOptionsFactory.cs

@ -81,10 +81,10 @@ namespace ICSharpCode.NRefactory.CSharp
AllowEventRemoveBlockInline = true, AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine, StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false, ElseNewLinePlacement = NewLinePlacement.SameLine,
PlaceCatchOnNewLine = false, CatchNewLinePlacement = NewLinePlacement.SameLine,
PlaceFinallyOnNewLine = false, FinallyNewLinePlacement = NewLinePlacement.SameLine,
PlaceWhileOnNewLine = false, WhileNewLinePlacement = NewLinePlacement.SameLine,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong, ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine, ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
@ -152,6 +152,7 @@ namespace ICSharpCode.NRefactory.CSharp
PropertyFormatting = PropertyFormatting.AllowOneLine, PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false, SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true, SpaceAfterMethodDeclarationParameterComma = true,
SpaceAfterDelegateDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false, SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true, SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false, SpaceBeforeLocalVariableDeclarationComma = false,
@ -175,6 +176,21 @@ namespace ICSharpCode.NRefactory.CSharp
BlankLinesBetweenMembers = 1, BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true, KeepCommentsAtFirstColumn = true,
ChainedMethodCallWrapping = Wrapping.DoNotChange,
MethodCallArgumentWrapping = Wrapping.DoNotChange,
NewLineAferMethodCallOpenParentheses = true,
MethodCallClosingParenthesesOnNewLine = true,
IndexerArgumentWrapping = Wrapping.DoNotChange,
NewLineAferIndexerOpenBracket = false,
IndexerClosingBracketOnNewLine = false,
IfElseBraceForcement = BraceForcement.DoNotChange,
ForBraceForcement = BraceForcement.DoNotChange,
ForEachBraceForcement = BraceForcement.DoNotChange,
WhileBraceForcement = BraceForcement.DoNotChange,
UsingBraceForcement = BraceForcement.DoNotChange,
FixedBraceForcement = BraceForcement.DoNotChange
}; };
} }
@ -182,6 +198,22 @@ namespace ICSharpCode.NRefactory.CSharp
/// Creates sharp develop indent style CSharpFormatting options. /// Creates sharp develop indent style CSharpFormatting options.
/// </summary> /// </summary>
public static CSharpFormattingOptions CreateSharpDevelop() public static CSharpFormattingOptions CreateSharpDevelop()
{
var baseOptions = CreateKRStyle();
baseOptions.IfElseBraceForcement = BraceForcement.AddBraces;
baseOptions.ForBraceForcement = BraceForcement.AddBraces;
baseOptions.ForEachBraceForcement = BraceForcement.AddBraces;
baseOptions.WhileBraceForcement = BraceForcement.AddBraces;
baseOptions.UsingBraceForcement = BraceForcement.AddBraces;
baseOptions.FixedBraceForcement = BraceForcement.AddBraces;
return baseOptions;
}
/// <summary>
/// The K&R style, so named because it was used in Kernighan and Ritchie's book The C Programming Language,
/// is commonly used in C. It is less common for C++, C#, and others.
/// </summary>
public static CSharpFormattingOptions CreateKRStyle ()
{ {
return new CSharpFormattingOptions () { return new CSharpFormattingOptions () {
IndentNamespaceBody = true, IndentNamespaceBody = true,
@ -219,10 +251,10 @@ namespace ICSharpCode.NRefactory.CSharp
AllowEventRemoveBlockInline = true, AllowEventRemoveBlockInline = true,
StatementBraceStyle = BraceStyle.EndOfLine, StatementBraceStyle = BraceStyle.EndOfLine,
PlaceElseOnNewLine = false, ElseNewLinePlacement = NewLinePlacement.SameLine,
PlaceCatchOnNewLine = false, CatchNewLinePlacement = NewLinePlacement.SameLine,
PlaceFinallyOnNewLine = false, FinallyNewLinePlacement = NewLinePlacement.SameLine,
PlaceWhileOnNewLine = false, WhileNewLinePlacement = NewLinePlacement.SameLine,
ArrayInitializerWrapping = Wrapping.WrapIfTooLong, ArrayInitializerWrapping = Wrapping.WrapIfTooLong,
ArrayInitializerBraceStyle = BraceStyle.EndOfLine, ArrayInitializerBraceStyle = BraceStyle.EndOfLine,
@ -291,6 +323,7 @@ namespace ICSharpCode.NRefactory.CSharp
PropertyFormatting = PropertyFormatting.AllowOneLine, PropertyFormatting = PropertyFormatting.AllowOneLine,
SpaceBeforeMethodDeclarationParameterComma = false, SpaceBeforeMethodDeclarationParameterComma = false,
SpaceAfterMethodDeclarationParameterComma = true, SpaceAfterMethodDeclarationParameterComma = true,
SpaceAfterDelegateDeclarationParameterComma = true,
SpaceBeforeFieldDeclarationComma = false, SpaceBeforeFieldDeclarationComma = false,
SpaceAfterFieldDeclarationComma = true, SpaceAfterFieldDeclarationComma = true,
SpaceBeforeLocalVariableDeclarationComma = false, SpaceBeforeLocalVariableDeclarationComma = false,
@ -313,6 +346,21 @@ namespace ICSharpCode.NRefactory.CSharp
BlankLinesBetweenMembers = 1, BlankLinesBetweenMembers = 1,
KeepCommentsAtFirstColumn = true, KeepCommentsAtFirstColumn = true,
ChainedMethodCallWrapping = Wrapping.DoNotChange,
MethodCallArgumentWrapping = Wrapping.DoNotChange,
NewLineAferMethodCallOpenParentheses = true,
MethodCallClosingParenthesesOnNewLine = true,
IndexerArgumentWrapping = Wrapping.DoNotChange,
NewLineAferIndexerOpenBracket = false,
IndexerClosingBracketOnNewLine = false,
IfElseBraceForcement = BraceForcement.DoNotChange,
ForBraceForcement = BraceForcement.DoNotChange,
ForEachBraceForcement = BraceForcement.DoNotChange,
WhileBraceForcement = BraceForcement.DoNotChange,
UsingBraceForcement = BraceForcement.DoNotChange,
FixedBraceForcement = BraceForcement.DoNotChange
}; };
} }
@ -321,19 +369,65 @@ namespace ICSharpCode.NRefactory.CSharp
/// </summary> /// </summary>
public static CSharpFormattingOptions CreateAllman() public static CSharpFormattingOptions CreateAllman()
{ {
var baseOptions = CreateSharpDevelop(); var baseOptions = CreateKRStyle();
baseOptions.AnonymousMethodBraceStyle = BraceStyle.EndOfLine; baseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLine;
baseOptions.PropertyBraceStyle = BraceStyle.EndOfLine; baseOptions.PropertyBraceStyle = BraceStyle.NextLine;
baseOptions.PropertyGetBraceStyle = BraceStyle.EndOfLine; baseOptions.PropertyGetBraceStyle = BraceStyle.NextLine;
baseOptions.PropertySetBraceStyle = BraceStyle.EndOfLine; baseOptions.PropertySetBraceStyle = BraceStyle.NextLine;
baseOptions.EventBraceStyle = BraceStyle.EndOfLine; baseOptions.EventBraceStyle = BraceStyle.NextLine;
baseOptions.EventAddBraceStyle = BraceStyle.EndOfLine; baseOptions.EventAddBraceStyle = BraceStyle.NextLine;
baseOptions.EventRemoveBraceStyle = BraceStyle.EndOfLine; baseOptions.EventRemoveBraceStyle = BraceStyle.NextLine;
baseOptions.StatementBraceStyle = BraceStyle.EndOfLine; baseOptions.StatementBraceStyle = BraceStyle.NextLine;
baseOptions.ArrayInitializerBraceStyle = BraceStyle.EndOfLine; baseOptions.ArrayInitializerBraceStyle = BraceStyle.NextLine;
return baseOptions; return baseOptions;
} }
/// <summary>
/// The Whitesmiths style, also called Wishart style to a lesser extent, is less common today than the previous three. It was originally used in the documentation for the first commercial C compiler, the Whitesmiths Compiler.
/// </summary>
public static CSharpFormattingOptions CreateWhitesmiths()
{
var baseOptions = CreateKRStyle();
baseOptions.NamespaceBraceStyle = BraceStyle.NextLineShifted;
baseOptions.ClassBraceStyle = BraceStyle.NextLineShifted;
baseOptions.InterfaceBraceStyle = BraceStyle.NextLineShifted;
baseOptions.StructBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EnumBraceStyle = BraceStyle.NextLineShifted;
baseOptions.MethodBraceStyle = BraceStyle.NextLineShifted;
baseOptions.ConstructorBraceStyle = BraceStyle.NextLineShifted;
baseOptions.DestructorBraceStyle = BraceStyle.NextLineShifted;
baseOptions.AnonymousMethodBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertyBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertyGetBraceStyle = BraceStyle.NextLineShifted;
baseOptions.PropertySetBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventAddBraceStyle = BraceStyle.NextLineShifted;
baseOptions.EventRemoveBraceStyle = BraceStyle.NextLineShifted;
baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted;
return baseOptions;
}
/// <summary>
/// Like the Allman and Whitesmiths styles, GNU style puts braces on a line by themselves, indented by 2 spaces,
/// except when opening a function definition, where they are not indented.
/// In either case, the contained code is indented by 2 spaces from the braces.
/// Popularised by Richard Stallman, the layout may be influenced by his background of writing Lisp code.
/// In Lisp the equivalent to a block (a progn)
/// is a first class data entity and giving it its own indent level helps to emphasize that,
/// whereas in C a block is just syntax.
/// Although not directly related to indentation, GNU coding style also includes a space before the bracketed
/// list of arguments to a function.
/// </summary>
public static CSharpFormattingOptions CreateGNU()
{
var baseOptions = CreateAllman();
baseOptions.StatementBraceStyle = BraceStyle.NextLineShifted2;
return baseOptions;
}
} }
} }

6
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/GeneratedCodeSettings.cs

@ -1,4 +1,4 @@
// //
// GeneratedCodeSettings.cs // GeneratedCodeSettings.cs
// //
// Author: // Author:
@ -177,7 +177,9 @@ namespace ICSharpCode.NRefactory.CSharp
var cmt = new Comment ("", CommentType.SingleLine); var cmt = new Comment ("", CommentType.SingleLine);
var cmt2 = new Comment (" " + label, CommentType.SingleLine); var cmt2 = new Comment (" " + label, CommentType.SingleLine);
var cmt3 = new Comment ("", CommentType.SingleLine); var cmt3 = new Comment ("", CommentType.SingleLine);
mem.Parent.InsertChildsBefore (mem, Roles.Comment, cmt, cmt2, cmt3); mem.Parent.InsertChildBefore (mem, cmt, Roles.Comment);
mem.Parent.InsertChildBefore (mem, cmt2, Roles.Comment);
mem.Parent.InsertChildBefore (mem, cmt3, Roles.Comment);
if (cmt.PrevSibling is EntityDeclaration) if (cmt.PrevSibling is EntityDeclaration)
mem.Parent.InsertChildBefore (cmt, new UnixNewLine (), Roles.NewLine); mem.Parent.InsertChildBefore (cmt, new UnixNewLine (), Roles.NewLine);

14
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/Indent.cs

@ -80,7 +80,19 @@ namespace ICSharpCode.NRefactory.CSharp
indentString = new string(' ', curIndent); indentString = new string(' ', curIndent);
return; return;
} }
indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize); indentString = new string('\t', curIndent / options.TabSize) + new string(' ', curIndent % options.TabSize) + new string (' ', ExtraSpaces);
}
int extraSpaces;
public int ExtraSpaces {
get {
return extraSpaces;
}
set {
extraSpaces = value;
Update();
}
} }
string indentString; string indentString;

10
NRefactory/ICSharpCode.NRefactory.CSharp/Formatter/TextEditorOptions.cs

@ -94,12 +94,22 @@ namespace ICSharpCode.NRefactory.CSharp
set; set;
} }
/// <summary>
/// Gets or sets the length of the desired line length. The formatting engine will wrap at wrap points set to Wrapping.WrapIfTooLong if the line length is too long.
/// 0 means do not wrap.
/// </summary>
public int WrapLineLength {
get;
set;
}
public TextEditorOptions() public TextEditorOptions()
{ {
TabsToSpaces = false; TabsToSpaces = false;
TabSize = 4; TabSize = 4;
IndentSize = 4; IndentSize = 4;
ContinuationIndent = 4; ContinuationIndent = 4;
WrapLineLength = 0;
EolMarker = Environment.NewLine; EolMarker = Environment.NewLine;
} }
} }

159
NRefactory/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj

@ -14,12 +14,13 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<ProductVersion>10.0.0</ProductVersion> <ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<SignAssembly>true</SignAssembly> <SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>..\ICSharpCode.NRefactory.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>..\ICSharpCode.NRefactory.snk</AssemblyOriginatorKeyFile>
<DelaySign>False</DelaySign> <DelaySign>False</DelaySign>
<AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode>
<DocumentationFile>..\ICSharpCode.NRefactory\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml</DocumentationFile> <DocumentationFile>..\bin\$(Configuration)\ICSharpCode.NRefactory.CSharp.xml</DocumentationFile>
<NoWarn>1591,1587,1570</NoWarn> <NoWarn>1591,1587,1570</NoWarn>
<OutputPath>..\bin\$(Configuration)\</OutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
@ -29,25 +30,43 @@
<FileAlignment>4096</FileAlignment> <FileAlignment>4096</FileAlignment>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Debug\</OutputPath>
<Optimize>False</Optimize> <Optimize>False</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;FULL_AST</DefineConstants> <DefineConstants>DEBUG;TRACE;FULL_AST;NET_4_0</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>..\ICSharpCode.NRefactory\bin\Release\</OutputPath>
<Optimize>True</Optimize> <Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;FULL_AST</DefineConstants> <DefineConstants>TRACE;FULL_AST;NET_4_0</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType> <DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols> <DebugSymbols>false</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType> <DebugType>Full</DebugType>
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Debug' ">
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE;FULL_AST;NET_4_0;NET_4_5</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Debug|AnyCPU' ">
<DebugType>Full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'net_4_5_Release' ">
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE;FULL_AST;NET_4_0;NET_4_5</DefineConstants>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'net_4_5_Release|AnyCPU' ">
<DebugType>PdbOnly</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core"> <Reference Include="System.Core">
@ -70,7 +89,7 @@
<Compile Include="Ast\AstType.cs" /> <Compile Include="Ast\AstType.cs" />
<Compile Include="Ast\DocumentationReference.cs" /> <Compile Include="Ast\DocumentationReference.cs" />
<Compile Include="Ast\IdentifierExpressionBackreference.cs" /> <Compile Include="Ast\IdentifierExpressionBackreference.cs" />
<Compile Include="Ast\CompilationUnit.cs" /> <Compile Include="Ast\SyntaxTree.cs" />
<Compile Include="Ast\ComposedType.cs" /> <Compile Include="Ast\ComposedType.cs" />
<Compile Include="Ast\CSharpModifierToken.cs" /> <Compile Include="Ast\CSharpModifierToken.cs" />
<Compile Include="Ast\CSharpTokenNode.cs" /> <Compile Include="Ast\CSharpTokenNode.cs" />
@ -131,6 +150,7 @@
<Compile Include="Ast\Modifiers.cs" /> <Compile Include="Ast\Modifiers.cs" />
<Compile Include="Ast\NodeType.cs" /> <Compile Include="Ast\NodeType.cs" />
<Compile Include="Ast\ObservableAstVisitor.cs" /> <Compile Include="Ast\ObservableAstVisitor.cs" />
<Compile Include="Ast\old_ObservableAstVisitor.cs" />
<Compile Include="Ast\PrimitiveType.cs" /> <Compile Include="Ast\PrimitiveType.cs" />
<Compile Include="Ast\SimpleType.cs" /> <Compile Include="Ast\SimpleType.cs" />
<Compile Include="Ast\Statements\BlockStatement.cs" /> <Compile Include="Ast\Statements\BlockStatement.cs" />
@ -184,6 +204,7 @@
<Compile Include="OutputVisitor\IOutputFormatter.cs" /> <Compile Include="OutputVisitor\IOutputFormatter.cs" />
<Compile Include="OutputVisitor\CSharpOutputVisitor.cs" /> <Compile Include="OutputVisitor\CSharpOutputVisitor.cs" />
<Compile Include="OutputVisitor\TextWriterOutputFormatter.cs" /> <Compile Include="OutputVisitor\TextWriterOutputFormatter.cs" />
<Compile Include="Parser\CompilerSettings.cs" />
<Compile Include="Parser\CSharpParser.cs" /> <Compile Include="Parser\CSharpParser.cs" />
<Compile Include="Parser\mcs\anonymous.cs" /> <Compile Include="Parser\mcs\anonymous.cs" />
<Compile Include="Parser\mcs\argument.cs" /> <Compile Include="Parser\mcs\argument.cs" />
@ -241,14 +262,80 @@
<Compile Include="Parser\mcs\typespec.cs" /> <Compile Include="Parser\mcs\typespec.cs" />
<Compile Include="Parser\mcs\visit.cs" /> <Compile Include="Parser\mcs\visit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="QueryExpressionExpander.cs" />
<Compile Include="Refactoring\CodeActions\ConvertAsToCastAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertCastToAsAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertConditionalToIfAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertExplicitToImplicitImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertIfToConditionalAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertIfToSwitchAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertImplicitToExplicitImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaBodyExpressionToStatementAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaBodyStatementToExpressionAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertSwitchToIfAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateCustomEventImplementationAction.cs" />
<Compile Include="Refactoring\CodeActions\CreateOverloadWithoutParameterAction.cs" />
<Compile Include="Refactoring\CodeActions\JoinDeclarationAndAssignmentAction.cs" />
<Compile Include="Refactoring\CodeActions\JoinStringAction.cs" />
<Compile Include="Refactoring\CodeActions\MergeNestedIfAction.cs" />
<Compile Include="Refactoring\CodeActions\NegateRelationalExpressionAction.cs" />
<Compile Include="Refactoring\CodeActions\PutInsideUsingAction.cs" />
<Compile Include="Refactoring\CodeActions\SplitDeclarationListAction.cs" />
<Compile Include="Refactoring\CodeActions\UseStringFormatAction.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToDisposedClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\AccessToModifiedClosureIssue.cs" />
<Compile Include="Refactoring\CodeIssues\AccessToClosureIssues\LocalVariableNamePicker.cs" />
<Compile Include="Refactoring\CodeIssues\AssignmentMadeToSameVariableIssue.cs" />
<Compile Include="Refactoring\CodeIssues\BitwiseOperationOnNonFlagsEnumIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CastExpressionOfIncompatibleTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CompareBooleanWithTrueOrFalseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CompareFloatWithEqualityOperatorIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ConstantConditionIssue.cs" />
<Compile Include="Refactoring\CodeIssues\DoubleNegationIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExpressionIsAlwaysOfProvidedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExpressionIsNeverOfProvidedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MethodNeverReturnsIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MethodOverloadHidesOptionalParameterIssue.cs" />
<Compile Include="Refactoring\CodeIssues\NegativeRelationalExpressionIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ExplicitConversionInForEachIssue.cs" /> <Compile Include="Refactoring\CodeIssues\ExplicitConversionInForEachIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ForControlVariableNotModifiedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\IdenticalConditionalBranchIssue.cs" />
<Compile Include="Refactoring\CodeIssues\MultipleEnumerationIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantArrayInitializerCommaIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantAssignmentIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantAttributeParenthesesIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantCaseLabelIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantElseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantFieldInitializerIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantObjectCreationArgumentListIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantObjectOrCollectionInitializerIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantTypeCastIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ReferenceEqualsCalledWithValueTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\UnreachableCodeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\LocalVariableHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\ParameterHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableHidesMemberIssue\VariableHidesMemberIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\LocalVariableOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\LocalVariableNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\ParameterNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\TypeParameterNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableNotUsedIssues\VariableNotUsedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\ParameterOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\VariableOnlyAssignedIssues\VariableOnlyAssignedIssue.cs" />
<Compile Include="Refactoring\DocumentScript.cs" /> <Compile Include="Refactoring\DocumentScript.cs" />
<Compile Include="Refactoring\CodeActions\ExtractAnonymousMethodAction.cs" />
<Compile Include="Refactoring\LambdaHelper.cs" />
<Compile Include="Refactoring\PatternHelper.cs" /> <Compile Include="Refactoring\PatternHelper.cs" />
<Compile Include="Refactoring\RefactoringAstHelper.cs" /> <Compile Include="Refactoring\RefactoringAstHelper.cs" />
<Compile Include="Refactoring\RefactoringContext.cs" /> <Compile Include="Refactoring\RefactoringContext.cs" />
<Compile Include="Refactoring\Script.cs" /> <Compile Include="Refactoring\Script.cs" />
<Compile Include="Refactoring\TypeCompatibilityHelper.cs" />
<Compile Include="Refactoring\TypeSystemAstBuilder.cs" /> <Compile Include="Refactoring\TypeSystemAstBuilder.cs" />
<Compile Include="Refactoring\VariableReferenceGraph.cs" />
<Compile Include="Resolver\CompositeResolveVisitorNavigator.cs" /> <Compile Include="Resolver\CompositeResolveVisitorNavigator.cs" />
<Compile Include="Resolver\DynamicInvocationResolveResult.cs" />
<Compile Include="Resolver\DynamicMemberResolveResult.cs" />
<Compile Include="Resolver\CSharpConversions.cs" /> <Compile Include="Resolver\CSharpConversions.cs" />
<Compile Include="Resolver\CSharpAstResolver.cs" /> <Compile Include="Resolver\CSharpAstResolver.cs" />
<Compile Include="Resolver\CSharpInvocationResolveResult.cs" /> <Compile Include="Resolver\CSharpInvocationResolveResult.cs" />
@ -271,14 +358,14 @@
<Compile Include="Resolver\TypeInference.cs" /> <Compile Include="Resolver\TypeInference.cs" />
<Compile Include="Completion\ICompletionDataFactory.cs" /> <Compile Include="Completion\ICompletionDataFactory.cs" />
<Compile Include="Completion\IParameterCompletionDataFactory.cs" /> <Compile Include="Completion\IParameterCompletionDataFactory.cs" />
<Compile Include="SimpleNameLookupMode.cs" /> <Compile Include="NameLookupMode.cs" />
<Compile Include="TypeSystem\AliasNamespaceReference.cs" /> <Compile Include="TypeSystem\AliasNamespaceReference.cs" />
<Compile Include="TypeSystem\AttributeTypeReference.cs" /> <Compile Include="TypeSystem\AttributeTypeReference.cs" />
<Compile Include="TypeSystem\ConstantValues.cs" /> <Compile Include="TypeSystem\ConstantValues.cs" />
<Compile Include="TypeSystem\CSharpAssembly.cs" /> <Compile Include="TypeSystem\CSharpAssembly.cs" />
<Compile Include="TypeSystem\CSharpAttribute.cs" /> <Compile Include="TypeSystem\CSharpAttribute.cs" />
<Compile Include="TypeSystem\CSharpDocumentationComment.cs" /> <Compile Include="TypeSystem\CSharpDocumentationComment.cs" />
<Compile Include="TypeSystem\CSharpParsedFile.cs" /> <Compile Include="TypeSystem\CSharpUnresolvedFile.cs" />
<Compile Include="TypeSystem\CSharpUnresolvedTypeDefinition.cs" /> <Compile Include="TypeSystem\CSharpUnresolvedTypeDefinition.cs" />
<Compile Include="TypeSystem\CSharpTypeResolveContext.cs" /> <Compile Include="TypeSystem\CSharpTypeResolveContext.cs" />
<Compile Include="TypeSystem\ResolvedUsingScope.cs" /> <Compile Include="TypeSystem\ResolvedUsingScope.cs" />
@ -294,7 +381,6 @@
<Compile Include="Completion\CSharpCompletionEngine.cs" /> <Compile Include="Completion\CSharpCompletionEngine.cs" />
<Compile Include="Completion\CSharpCompletionEngineBase.cs" /> <Compile Include="Completion\CSharpCompletionEngineBase.cs" />
<Compile Include="Completion\CSharpParameterCompletionEngine.cs" /> <Compile Include="Completion\CSharpParameterCompletionEngine.cs" />
<Compile Include="Completion\IMemberProvider.cs" />
<Compile Include="Parser\mcs\module.cs" /> <Compile Include="Parser\mcs\module.cs" />
<Compile Include="Parser\mcs\settings.cs" /> <Compile Include="Parser\mcs\settings.cs" />
<Compile Include="Parser\mcs\SourceMethodBuilder.cs" /> <Compile Include="Parser\mcs\SourceMethodBuilder.cs" />
@ -370,6 +456,48 @@
<Compile Include="Ast\GeneralScope\WhitespaceNode.cs" /> <Compile Include="Ast\GeneralScope\WhitespaceNode.cs" />
<Compile Include="Ast\GeneralScope\TextNode.cs" /> <Compile Include="Ast\GeneralScope\TextNode.cs" />
<Compile Include="Formatter\FormattingOptionsFactory.cs" /> <Compile Include="Formatter\FormattingOptionsFactory.cs" />
<Compile Include="Refactoring\CodeActions\ImplementInterfaceAction.cs" />
<Compile Include="Refactoring\CodeActions\ImplementInterfaceExplicitAction.cs" />
<Compile Include="Refactoring\CodeActions\ImplementAbstractMembersAction.cs" />
<Compile Include="Refactoring\CodeActions\RemoveRedundantCatchTypeAction.cs" />
<Compile Include="Refactoring\CodeActions\AddCatchTypeAction.cs" />
<Compile Include="Refactoring\CodeIssues\IncorrectExceptionParameterOrderingIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CallToVirtualFunctionFromConstructorIssue.cs" />
<Compile Include="Refactoring\CodeActions\StaticMethodInvocationToExtensionMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtensionMethodInvocationToStaticMethodInvocationAction.cs" />
<Compile Include="Refactoring\CodeActions\IterateViaForeachAction.cs" />
<Compile Include="Refactoring\CodeActions\ExtractFieldAction.cs" />
<Compile Include="Completion\ICompletionContextProvider.cs" />
<Compile Include="Refactoring\CodeIssues\ValueParameterUnusedIssue.cs" />
<Compile Include="Refactoring\NamingHelper.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\ConvertToInitializerAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\StatementsToInitializerConverter.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\InitializerPath.cs" />
<Compile Include="Refactoring\CodeActions\MoveToOuterScopeAction.cs" />
<Compile Include="Refactoring\CodeIssues\VariableDeclaredInWideScopeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\ParameterCanBeDemotedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\ITypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\HasMemberCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\TypeCriteriaCollector.cs" />
<Compile Include="Refactoring\CodeIssues\ReferenceToStaticMemberViaDerivedTypeIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\IsTypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\OptionalParameterCouldBeSkippedIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantCatchIssue.cs" />
<Compile Include="Refactoring\CodeIssues\RedundantToStringIssue.cs" />
<Compile Include="Refactoring\CodeIssues\CallToObjectEqualsViaBaseIssue.cs" />
<Compile Include="Refactoring\CodeIssues\IncorrectCallToObjectGetHashCodeIssue.cs" />
<Compile Include="Refactoring\CodeActions\ExtractMethod\VariableUsageAnalyzation.cs" />
<Compile Include="Refactoring\CodeIssues\FormatStringIssues\FormatStringIssue.cs" />
<Compile Include="Refactoring\CodeIssues\FormatStringIssues\FormatStringHelper.cs" />
<Compile Include="Refactoring\CodeActions\ConvertToInitializer\ConvertInitializerToExplicitInitializationsAction.cs" />
<Compile Include="Refactoring\CodeIssues\ExceptionRethrowIssue.cs" />
<Compile Include="Refactoring\CodeIssues\ThreadStaticOnInstanceFieldIssue.cs" />
<Compile Include="Refactoring\CodeIssues\StaticFieldInGenericTypeIssue.cs" />
<Compile Include="Parser\SeekableStreamReader.cs" />
<Compile Include="Refactoring\CodeActions\ConvertAnonymousDelegateToLambdaAction.cs" />
<Compile Include="Refactoring\CodeActions\ConvertLambdaToAnonymousDelegateAction.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\IsArrayTypeCriterion.cs" />
<Compile Include="Refactoring\CodeIssues\ParameterCanBeDemotedIssue\SupportsIndexingCriterion.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj"> <ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
@ -383,14 +511,17 @@
<Folder Include="Refactoring\CodeIssues\" /> <Folder Include="Refactoring\CodeIssues\" />
<Folder Include="Refactoring\CodeIssues\InconsistentNamingIssue\" /> <Folder Include="Refactoring\CodeIssues\InconsistentNamingIssue\" />
<Folder Include="Refactoring\CodeActions\ExtractMethod\" /> <Folder Include="Refactoring\CodeActions\ExtractMethod\" />
<Folder Include="Refactoring\CodeActions\ConvertToInitializer\" />
<Folder Include="Refactoring\CodeIssues\FormatStringIssues\" />
</ItemGroup> </ItemGroup>
<ProjectExtensions> <ProjectExtensions>
<MonoDevelop> <MonoDevelop>
<Properties> <Properties>
<Policies> <Policies>
<TextStylePolicy TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/plain" /> <TextStylePolicy TabsToSpaces="False" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
<TextStylePolicy FileWidth="120" TabWidth="4" EolMarker="Unix" inheritsSet="Mono" inheritsScope="text/plain" scope="text/x-csharp" /> <TextStylePolicy FileWidth="120" TabsToSpaces="False" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
<CSharpFormattingPolicy inheritsSet="1TBS" inheritsScope="text/x-csharp" scope="text/x-csharp" /> <CSharpFormattingPolicy IndentSwitchBody="True" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
<TextStylePolicy inheritsSet="null" scope="text/x-jay" />
</Policies> </Policies>
</Properties> </Properties>
</MonoDevelop> </MonoDevelop>

2
NRefactory/ICSharpCode.NRefactory.CSharp/SimpleNameLookupMode.cs → NRefactory/ICSharpCode.NRefactory.CSharp/NameLookupMode.cs

@ -20,7 +20,7 @@ using System;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
public enum SimpleNameLookupMode public enum NameLookupMode
{ {
/// <summary> /// <summary>
/// Normal name lookup in expressions /// Normal name lookup in expressions

17
NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs

@ -917,7 +917,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) public void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
{ {
StartNode(namedArgumentExpression); StartNode(namedArgumentExpression);
namedArgumentExpression.IdentifierToken.AcceptVisitor(this); namedArgumentExpression.NameToken.AcceptVisitor(this);
WriteToken(Roles.Colon); WriteToken(Roles.Colon);
Space(); Space();
namedArgumentExpression.Expression.AcceptVisitor(this); namedArgumentExpression.Expression.AcceptVisitor(this);
@ -927,7 +927,7 @@ namespace ICSharpCode.NRefactory.CSharp
public void VisitNamedExpression(NamedExpression namedExpression) public void VisitNamedExpression(NamedExpression namedExpression)
{ {
StartNode(namedExpression); StartNode(namedExpression);
namedExpression.IdentifierToken.AcceptVisitor(this); namedExpression.NameToken.AcceptVisitor(this);
Space(); Space();
WriteToken(Roles.Assign); WriteToken(Roles.Assign);
Space(); Space();
@ -1007,6 +1007,14 @@ namespace ICSharpCode.NRefactory.CSharp
EndNode(primitiveExpression); EndNode(primitiveExpression);
} }
public static string PrintPrimitiveValue(object val)
{
StringWriter writer = new StringWriter();
CSharpOutputVisitor visitor = new CSharpOutputVisitor(writer, new CSharpFormattingOptions());
visitor.WritePrimitiveValue(val);
return writer.ToString();
}
void WritePrimitiveValue(object val) void WritePrimitiveValue(object val)
{ {
if (val == null) { if (val == null) {
@ -2164,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteAttributes(indexerDeclaration.Attributes); WriteAttributes(indexerDeclaration.Attributes);
WriteModifiers(indexerDeclaration.ModifierTokens); WriteModifiers(indexerDeclaration.ModifierTokens);
indexerDeclaration.ReturnType.AcceptVisitor(this); indexerDeclaration.ReturnType.AcceptVisitor(this);
Space();
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType); WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword(IndexerDeclaration.ThisKeywordRole); WriteKeyword(IndexerDeclaration.ThisKeywordRole);
Space(policy.SpaceBeforeMethodDeclarationParentheses); Space(policy.SpaceBeforeMethodDeclarationParentheses);
@ -2296,10 +2305,10 @@ namespace ICSharpCode.NRefactory.CSharp
EndNode(variableInitializer); EndNode(variableInitializer);
} }
public void VisitCompilationUnit(CompilationUnit compilationUnit) public void VisitSyntaxTree(SyntaxTree syntaxTree)
{ {
// don't do node tracking as we visit all children directly // don't do node tracking as we visit all children directly
foreach (AstNode node in compilationUnit.Children) { foreach (AstNode node in syntaxTree.Children) {
node.AcceptVisitor(this); node.AcceptVisitor(this);
} }
} }

141
NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/CodeDomConvertVisitor.cs

@ -21,12 +21,12 @@ using System.CodeDom;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.CSharp.Resolver; using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.CSharp.TypeSystem; using ICSharpCode.NRefactory.CSharp.TypeSystem;
using ICSharpCode.NRefactory.PatternMatching; using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.Semantics; using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.CSharp namespace ICSharpCode.NRefactory.CSharp
{ {
@ -40,35 +40,44 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
//ICompilation compilation = MinimalResolveContext.Instance; //ICompilation compilation = MinimalResolveContext.Instance;
CSharpAstResolver resolver; CSharpAstResolver resolver;
bool useFullyQualifiedTypeNames;
/// <summary> /// <summary>
/// Gets/Sets whether the visitor should use fully-qualified type references. /// Gets/Sets whether the visitor should use fully-qualified type references.
/// </summary> /// </summary>
public bool UseFullyQualifiedTypeNames { public bool UseFullyQualifiedTypeNames { get; set; }
get { return useFullyQualifiedTypeNames; }
set { useFullyQualifiedTypeNames = value; } /// <summary>
/// Gets whether the visitor is allowed to produce snippet nodes for
/// code that cannot be converted.
/// The default is true. If this property is set to false,
/// unconvertible code will throw a NotSupportedException.
/// </summary>
public bool AllowSnippetNodes { get; set; }
public CodeDomConvertVisitor()
{
this.AllowSnippetNodes = true;
} }
/// <summary> /// <summary>
/// Converts a compilation unit to CodeDom. /// Converts a syntax tree to CodeDom.
/// </summary> /// </summary>
/// <param name="compilationUnit">The input compilation unit.</param> /// <param name="syntaxTree">The input syntax tree.</param>
/// <param name="compilation">The current compilation.</param> /// <param name="compilation">The current compilation.</param>
/// <param name="parsedFile">CSharpParsedFile, used for resolving.</param> /// <param name="unresolvedFile">CSharpUnresolvedFile, used for resolving.</param>
/// <returns>Converted CodeCompileUnit</returns> /// <returns>Converted CodeCompileUnit</returns>
/// <remarks> /// <remarks>
/// This conversion process requires a resolver because it needs to distinguish field/property/event references etc. /// This conversion process requires a resolver because it needs to distinguish field/property/event references etc.
/// </remarks> /// </remarks>
public CodeCompileUnit Convert(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile) public CodeCompileUnit Convert(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile)
{ {
if (compilationUnit == null) if (syntaxTree == null)
throw new ArgumentNullException("compilationUnit"); throw new ArgumentNullException("syntaxTree");
if (compilation == null) if (compilation == null)
throw new ArgumentNullException("compilation"); throw new ArgumentNullException("compilation");
CSharpAstResolver resolver = new CSharpAstResolver(compilation, compilationUnit, parsedFile); CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile);
return (CodeCompileUnit)Convert(compilationUnit, resolver); return (CodeCompileUnit)Convert(syntaxTree, resolver);
} }
/// <summary> /// <summary>
@ -136,8 +145,16 @@ namespace ICSharpCode.NRefactory.CSharp
CodeTypeReference Convert(IType type) CodeTypeReference Convert(IType type)
{ {
if (type.Kind == TypeKind.Array) {
ArrayType a = (ArrayType)type;
return new CodeTypeReference(Convert(a.ElementType), a.Dimensions);
} else if (type is ParameterizedType) {
var pt = (ParameterizedType)type;
return new CodeTypeReference(pt.GetDefinition().ReflectionName, pt.TypeArguments.Select(Convert).ToArray());
} else {
return new CodeTypeReference(type.ReflectionName); return new CodeTypeReference(type.ReflectionName);
} }
}
CodeStatement Convert(Statement stmt) CodeStatement Convert(Statement stmt)
{ {
@ -148,6 +165,8 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
List<CodeStatement> result = new List<CodeStatement>(); List<CodeStatement> result = new List<CodeStatement>();
foreach (Statement stmt in block.Statements) { foreach (Statement stmt in block.Statements) {
if (stmt is EmptyStatement)
continue;
CodeStatement s = Convert(stmt); CodeStatement s = Convert(stmt);
if (s != null) if (s != null)
result.Add(s); result.Add(s);
@ -160,6 +179,8 @@ namespace ICSharpCode.NRefactory.CSharp
BlockStatement block = embeddedStatement as BlockStatement; BlockStatement block = embeddedStatement as BlockStatement;
if (block != null) { if (block != null) {
return ConvertBlock(block); return ConvertBlock(block);
} else if (embeddedStatement is EmptyStatement) {
return new CodeStatement[0];
} }
CodeStatement s = Convert(embeddedStatement); CodeStatement s = Convert(embeddedStatement);
if (s != null) if (s != null)
@ -170,6 +191,8 @@ namespace ICSharpCode.NRefactory.CSharp
string MakeSnippet(AstNode node) string MakeSnippet(AstNode node)
{ {
if (!AllowSnippetNodes)
throw new NotSupportedException();
StringWriter w = new StringWriter(); StringWriter w = new StringWriter();
CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ()); CSharpOutputVisitor v = new CSharpOutputVisitor(w, FormattingOptionsFactory.CreateMono ());
node.AcceptVisitor(v); node.AcceptVisitor(v);
@ -371,7 +394,7 @@ namespace ICSharpCode.NRefactory.CSharp
TypeResolveResult trr = rr as TypeResolveResult; TypeResolveResult trr = rr as TypeResolveResult;
if (trr != null) { if (trr != null) {
CodeTypeReference typeRef; CodeTypeReference typeRef;
if (useFullyQualifiedTypeNames) { if (UseFullyQualifiedTypeNames) {
typeRef = Convert(trr.Type); typeRef = Convert(trr.Type);
} else { } else {
typeRef = new CodeTypeReference(identifierExpression.Identifier); typeRef = new CodeTypeReference(identifierExpression.Identifier);
@ -380,7 +403,7 @@ namespace ICSharpCode.NRefactory.CSharp
return new CodeTypeReferenceExpression(typeRef); return new CodeTypeReferenceExpression(typeRef);
} }
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult; MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
if (mgrr != null) { if (mgrr != null || identifierExpression.TypeArguments.Any()) {
return new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), identifierExpression.Identifier, Convert(identifierExpression.TypeArguments)); return new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), identifierExpression.Identifier, Convert(identifierExpression.TypeArguments));
} }
return new CodeVariableReferenceExpression(identifierExpression.Identifier); return new CodeVariableReferenceExpression(identifierExpression.Identifier);
@ -635,7 +658,7 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (Expression expr in attribute.Arguments) { foreach (Expression expr in attribute.Arguments) {
NamedExpression ne = expr as NamedExpression; NamedExpression ne = expr as NamedExpression;
if (ne != null) if (ne != null)
attr.Arguments.Add(new CodeAttributeArgument(ne.Identifier, Convert(ne.Expression))); attr.Arguments.Add(new CodeAttributeArgument(ne.Name, Convert(ne.Expression)));
else else
attr.Arguments.Add(new CodeAttributeArgument(Convert(expr))); attr.Arguments.Add(new CodeAttributeArgument(Convert(expr)));
} }
@ -658,7 +681,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration) CodeObject IAstVisitor<CodeObject>.VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
{ {
CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name); CodeTypeDelegate d = new CodeTypeDelegate(delegateDeclaration.Name);
d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers); d.Attributes = ConvertMemberAttributes(delegateDeclaration.Modifiers, EntityType.TypeDefinition);
d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes)); d.CustomAttributes.AddRange(Convert(delegateDeclaration.Attributes));
d.ReturnType = Convert(delegateDeclaration.ReturnType); d.ReturnType = Convert(delegateDeclaration.ReturnType);
d.Parameters.AddRange(Convert(delegateDeclaration.Parameters)); d.Parameters.AddRange(Convert(delegateDeclaration.Parameters));
@ -666,13 +689,15 @@ namespace ICSharpCode.NRefactory.CSharp
return d; return d;
} }
static MemberAttributes ConvertMemberAttributes(Modifiers modifiers) MemberAttributes ConvertMemberAttributes(Modifiers modifiers, EntityType entityType)
{ {
MemberAttributes a = 0; MemberAttributes a = 0;
if ((modifiers & Modifiers.Abstract) != 0) if ((modifiers & Modifiers.Abstract) != 0)
a |= MemberAttributes.Abstract; a |= MemberAttributes.Abstract;
if ((modifiers & Modifiers.Sealed) != 0) if ((modifiers & Modifiers.Sealed) != 0)
a |= MemberAttributes.Final; a |= MemberAttributes.Final;
if (entityType != EntityType.TypeDefinition && (modifiers & (Modifiers.Abstract | Modifiers.Override | Modifiers.Virtual)) == 0)
a |= MemberAttributes.Final;
if ((modifiers & Modifiers.Static) != 0) if ((modifiers & Modifiers.Static) != 0)
a |= MemberAttributes.Static; a |= MemberAttributes.Static;
if ((modifiers & Modifiers.Override) != 0) if ((modifiers & Modifiers.Override) != 0)
@ -719,7 +744,7 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
//bool isNestedType = typeStack.Count > 0; //bool isNestedType = typeStack.Count > 0;
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name); CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeDeclaration.Name);
typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers); typeDecl.Attributes = ConvertMemberAttributes(typeDeclaration.Modifiers, EntityType.TypeDefinition);
typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes)); typeDecl.CustomAttributes.AddRange(Convert(typeDeclaration.Attributes));
switch (typeDeclaration.ClassType) { switch (typeDeclaration.ClassType) {
@ -809,7 +834,12 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitEmptyStatement(EmptyStatement emptyStatement) CodeObject IAstVisitor<CodeObject>.VisitEmptyStatement(EmptyStatement emptyStatement)
{ {
return null; return EmptyStatement();
}
CodeStatement EmptyStatement()
{
return new CodeExpressionStatement(new CodeObjectCreateExpression(new CodeTypeReference(typeof(object))));
} }
CodeObject IAstVisitor<CodeObject>.VisitExpressionStatement(ExpressionStatement expressionStatement) CodeObject IAstVisitor<CodeObject>.VisitExpressionStatement(ExpressionStatement expressionStatement)
@ -817,10 +847,55 @@ namespace ICSharpCode.NRefactory.CSharp
AssignmentExpression assignment = expressionStatement.Expression as AssignmentExpression; AssignmentExpression assignment = expressionStatement.Expression as AssignmentExpression;
if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign) { if (assignment != null && assignment.Operator == AssignmentOperatorType.Assign) {
return new CodeAssignStatement(Convert(assignment.Left), Convert(assignment.Right)); return new CodeAssignStatement(Convert(assignment.Left), Convert(assignment.Right));
} else if (assignment != null && CanBeDuplicatedForCompoundAssignment(assignment.Left)) {
CodeBinaryOperatorType op;
switch (assignment.Operator) {
case AssignmentOperatorType.Add:
op = CodeBinaryOperatorType.Add;
break;
case AssignmentOperatorType.Subtract:
op = CodeBinaryOperatorType.Subtract;
break;
case AssignmentOperatorType.Multiply:
op = CodeBinaryOperatorType.Multiply;
break;
case AssignmentOperatorType.Divide:
op = CodeBinaryOperatorType.Divide;
break;
case AssignmentOperatorType.Modulus:
op = CodeBinaryOperatorType.Modulus;
break;
case AssignmentOperatorType.BitwiseAnd:
op = CodeBinaryOperatorType.BitwiseAnd;
break;
case AssignmentOperatorType.BitwiseOr:
op = CodeBinaryOperatorType.BitwiseOr;
break;
default:
return MakeSnippetStatement(expressionStatement);
}
var cboe = new CodeBinaryOperatorExpression(Convert(assignment.Left), op, Convert(assignment.Right));
return new CodeAssignStatement(Convert(assignment.Left), cboe);
}
UnaryOperatorExpression unary = expressionStatement.Expression as UnaryOperatorExpression;
if (unary != null && CanBeDuplicatedForCompoundAssignment(unary.Expression)) {
var op = unary.Operator;
if (op == UnaryOperatorType.Increment || op == UnaryOperatorType.PostIncrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
} else if (op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostDecrement) {
var cboe = new CodeBinaryOperatorExpression(Convert(unary.Expression), CodeBinaryOperatorType.Subtract, new CodePrimitiveExpression(1));
return new CodeAssignStatement(Convert(unary.Expression), cboe);
}
} }
return new CodeExpressionStatement(Convert(expressionStatement.Expression)); return new CodeExpressionStatement(Convert(expressionStatement.Expression));
} }
bool CanBeDuplicatedForCompoundAssignment(Expression expr)
{
return expr is IdentifierExpression;
}
CodeObject IAstVisitor<CodeObject>.VisitFixedStatement(FixedStatement fixedStatement) CodeObject IAstVisitor<CodeObject>.VisitFixedStatement(FixedStatement fixedStatement)
{ {
return MakeSnippetStatement(fixedStatement); return MakeSnippetStatement(fixedStatement);
@ -956,7 +1031,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitWhileStatement(WhileStatement whileStatement) CodeObject IAstVisitor<CodeObject>.VisitWhileStatement(WhileStatement whileStatement)
{ {
return new CodeIterationStatement(null, Convert(whileStatement.Condition), null, ConvertEmbeddedStatement(whileStatement.EmbeddedStatement)); return new CodeIterationStatement(EmptyStatement(), Convert(whileStatement.Condition), EmptyStatement(), ConvertEmbeddedStatement(whileStatement.EmbeddedStatement));
} }
CodeObject IAstVisitor<CodeObject>.VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement) CodeObject IAstVisitor<CodeObject>.VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
@ -977,7 +1052,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration) CodeObject IAstVisitor<CodeObject>.VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{ {
CodeConstructor ctor = new CodeConstructor(); CodeConstructor ctor = new CodeConstructor();
ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers); ctor.Attributes = ConvertMemberAttributes(constructorDeclaration.Modifiers, EntityType.Constructor);
ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes)); ctor.CustomAttributes.AddRange(Convert(constructorDeclaration.Attributes));
if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) { if (constructorDeclaration.Initializer.ConstructorInitializerType == ConstructorInitializerType.This) {
ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments)); ctor.ChainedConstructorArgs.AddRange(Convert(constructorDeclaration.Initializer.Arguments));
@ -1019,7 +1094,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
CodeMemberEvent e = new CodeMemberEvent(); CodeMemberEvent e = new CodeMemberEvent();
e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers); e.Attributes = ConvertMemberAttributes(eventDeclaration.Modifiers, EntityType.Event);
e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes)); e.CustomAttributes.AddRange(Convert(eventDeclaration.Attributes));
e.Name = vi.Name; e.Name = vi.Name;
e.Type = Convert(eventDeclaration.ReturnType); e.Type = Convert(eventDeclaration.ReturnType);
@ -1037,7 +1112,7 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
foreach (VariableInitializer vi in fieldDeclaration.Variables) { foreach (VariableInitializer vi in fieldDeclaration.Variables) {
CodeMemberField f = new CodeMemberField(Convert(fieldDeclaration.ReturnType), vi.Name); CodeMemberField f = new CodeMemberField(Convert(fieldDeclaration.ReturnType), vi.Name);
f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers); f.Attributes = ConvertMemberAttributes(fieldDeclaration.Modifiers, EntityType.Field);
f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes)); f.CustomAttributes.AddRange(Convert(fieldDeclaration.Attributes));
f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType); f.InitExpression = ConvertVariableInitializer(vi.Initializer, fieldDeclaration.ReturnType);
AddTypeMember(f); AddTypeMember(f);
@ -1048,7 +1123,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration) CodeObject IAstVisitor<CodeObject>.VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
{ {
CodeMemberProperty p = new CodeMemberProperty(); CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers); p.Attributes = ConvertMemberAttributes(indexerDeclaration.Modifiers, EntityType.Indexer);
p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes)); p.CustomAttributes.AddRange(Convert(indexerDeclaration.Attributes));
p.Name = "Items"; p.Name = "Items";
p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType); p.PrivateImplementationType = Convert(indexerDeclaration.PrivateImplementationType);
@ -1069,7 +1144,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitMethodDeclaration(MethodDeclaration methodDeclaration) CodeObject IAstVisitor<CodeObject>.VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{ {
CodeMemberMethod m = new CodeMemberMethod(); CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers); m.Attributes = ConvertMemberAttributes(methodDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); m.CustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); m.ReturnTypeCustomAttributes.AddRange(Convert(methodDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1087,7 +1162,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration) CodeObject IAstVisitor<CodeObject>.VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
{ {
CodeMemberMethod m = new CodeMemberMethod(); CodeMemberMethod m = new CodeMemberMethod();
m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers); m.Attributes = ConvertMemberAttributes(operatorDeclaration.Modifiers, EntityType.Method);
m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return"))); m.CustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget != "return")));
m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return"))); m.ReturnTypeCustomAttributes.AddRange(Convert(operatorDeclaration.Attributes.Where(a => a.AttributeTarget == "return")));
@ -1129,7 +1204,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration) CodeObject IAstVisitor<CodeObject>.VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{ {
CodeMemberProperty p = new CodeMemberProperty(); CodeMemberProperty p = new CodeMemberProperty();
p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers); p.Attributes = ConvertMemberAttributes(propertyDeclaration.Modifiers, EntityType.Property);
p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes)); p.CustomAttributes.AddRange(Convert(propertyDeclaration.Attributes));
p.Name = propertyDeclaration.Name; p.Name = propertyDeclaration.Name;
p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType); p.PrivateImplementationType = Convert(propertyDeclaration.PrivateImplementationType);
@ -1161,10 +1236,10 @@ namespace ICSharpCode.NRefactory.CSharp
throw new NotSupportedException(); // should be handled by the parent node throw new NotSupportedException(); // should be handled by the parent node
} }
CodeObject IAstVisitor<CodeObject>.VisitCompilationUnit(CompilationUnit compilationUnit) CodeObject IAstVisitor<CodeObject>.VisitSyntaxTree(SyntaxTree syntaxTree)
{ {
CodeCompileUnit cu = new CodeCompileUnit(); CodeCompileUnit cu = new CodeCompileUnit();
foreach (AstNode node in compilationUnit.Children) { foreach (AstNode node in syntaxTree.Children) {
CodeObject o = node.AcceptVisitor(this); CodeObject o = node.AcceptVisitor(this);
CodeNamespace ns = o as CodeNamespace; CodeNamespace ns = o as CodeNamespace;
@ -1181,7 +1256,7 @@ namespace ICSharpCode.NRefactory.CSharp
CodeObject IAstVisitor<CodeObject>.VisitSimpleType(SimpleType simpleType) CodeObject IAstVisitor<CodeObject>.VisitSimpleType(SimpleType simpleType)
{ {
if (useFullyQualifiedTypeNames) { if (UseFullyQualifiedTypeNames) {
IType type = Resolve(simpleType).Type; IType type = Resolve(simpleType).Type;
if (type.Kind != TypeKind.Unknown) if (type.Kind != TypeKind.Unknown)
return Convert(type); return Convert(type);
@ -1198,7 +1273,7 @@ namespace ICSharpCode.NRefactory.CSharp
tr.TypeArguments.AddRange(Convert(memberType.TypeArguments)); tr.TypeArguments.AddRange(Convert(memberType.TypeArguments));
return tr; return tr;
} }
if (useFullyQualifiedTypeNames || memberType.IsDoubleColon) { if (UseFullyQualifiedTypeNames || memberType.IsDoubleColon) {
IType type = Resolve(memberType).Type; IType type = Resolve(memberType).Type;
if (type.Kind != TypeKind.Unknown) if (type.Kind != TypeKind.Unknown)
return Convert(type); return Convert(type);
@ -1309,7 +1384,7 @@ namespace ICSharpCode.NRefactory.CSharp
return null; return null;
} }
CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern) CodeObject IAstVisitor<CodeObject>.VisitPatternPlaceholder(AstNode placeholder, Pattern pattern)
{ {
return null; return null;
} }

471
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs

@ -36,12 +36,14 @@ namespace ICSharpCode.NRefactory.CSharp
{ {
public class CSharpParser public class CSharpParser
{ {
CompilerSettings compilerSettings;
class ConversionVisitor : StructuralVisitor class ConversionVisitor : StructuralVisitor
{ {
CompilationUnit unit = new CompilationUnit (); SyntaxTree unit = new SyntaxTree ();
internal bool convertTypeSystemMode; internal bool convertTypeSystemMode;
public CompilationUnit Unit { public SyntaxTree Unit {
get { get {
return unit; return unit;
} }
@ -334,11 +336,15 @@ namespace ICSharpCode.NRefactory.CSharp
result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Colon); result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Colon);
} }
int attributeCount = 0;
foreach (var attr in GetAttributes (optAttributes)) { foreach (var attr in GetAttributes (optAttributes)) {
result.AddChild (attr, Roles.Attribute); result.AddChild (attr, Roles.Attribute);
attributeCount++;
} }
// Left and right bracket + commas between the attributes
int locCount = 2 + attributeCount - 1;
// optional comma // optional comma
if (loc != null && pos < loc.Count - 1 && !loc [pos].Equals (loc [pos + 1])) if (loc != null && pos < loc.Count - 1 && loc.Count == locCount + 1)
result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Comma); result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.Comma);
if (loc != null && pos < loc.Count) if (loc != null && pos < loc.Count)
result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.RBracket); result.AddChild (new CSharpTokenNode (Convert (loc [pos++])), Roles.RBracket);
@ -666,7 +672,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (namespaceStack.Count > 0) { if (namespaceStack.Count > 0) {
namespaceStack.Peek ().AddChild (child, NamespaceDeclaration.MemberRole); namespaceStack.Peek ().AddChild (child, NamespaceDeclaration.MemberRole);
} else { } else {
unit.AddChild (child, CompilationUnit.MemberRole); unit.AddChild (child, SyntaxTree.MemberRole);
} }
} }
@ -693,7 +699,12 @@ namespace ICSharpCode.NRefactory.CSharp
newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.LBrace); newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.LBrace);
typeStack.Push(newType); typeStack.Push(newType);
foreach (EnumMember member in e.Members) { foreach (var m in e.Members) {
EnumMember member = m as EnumMember;
if (member == null) {
Console.WriteLine("WARNING - ENUM MEMBER: " + m);
continue;
}
Visit(member); Visit(member);
if (location != null && curLoc < location.Count - 1) //last one is closing brace if (location != null && curLoc < location.Count - 1) //last one is closing brace
newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.Comma); newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++])), Roles.Comma);
@ -733,12 +744,13 @@ namespace ICSharpCode.NRefactory.CSharp
public override void Visit (FixedField f) public override void Visit (FixedField f)
{ {
var location = LocationsBag.GetMemberLocation (f); var location = LocationsBag.GetMemberLocation (f);
int locationIdx = 0;
var newField = new FixedFieldDeclaration (); var newField = new FixedFieldDeclaration ();
AddAttributeSection (newField, f); AddAttributeSection (newField, f);
AddModifiers (newField, location); AddModifiers (newField, location);
if (location != null && location.Count > 0) if (location != null && location.Count > 0)
newField.AddChild (new CSharpTokenNode (Convert (location [0])), FixedFieldDeclaration.FixedKeywordRole); newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), FixedFieldDeclaration.FixedKeywordRole);
if (f.TypeExpression != null) if (f.TypeExpression != null)
newField.AddChild (ConvertToType (f.TypeExpression), Roles.Type); newField.AddChild (ConvertToType (f.TypeExpression), Roles.Type);
@ -775,8 +787,8 @@ namespace ICSharpCode.NRefactory.CSharp
newField.AddChild (variable, FixedFieldDeclaration.VariableRole); newField.AddChild (variable, FixedFieldDeclaration.VariableRole);
} }
} }
if (location != null) if (location != null && location.Count > locationIdx)
newField.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Semicolon); newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx])), Roles.Semicolon);
typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole);
} }
@ -792,10 +804,10 @@ namespace ICSharpCode.NRefactory.CSharp
VariableInitializer variable = new VariableInitializer (); VariableInitializer variable = new VariableInitializer ();
variable.AddChild (Identifier.Create (f.MemberName.Name, Convert (f.MemberName.Location)), Roles.Identifier); variable.AddChild (Identifier.Create (f.MemberName.Name, Convert (f.MemberName.Location)), Roles.Identifier);
int locationIdx = 0;
if (f.Initializer != null) { if (f.Initializer != null) {
if (location != null) if (location != null)
variable.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Assign); variable.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), Roles.Assign);
variable.AddChild ((Expression)f.Initializer.Accept (this), Roles.Expression); variable.AddChild ((Expression)f.Initializer.Accept (this), Roles.Expression);
} }
newField.AddChild (variable, Roles.Variable); newField.AddChild (variable, Roles.Variable);
@ -815,8 +827,8 @@ namespace ICSharpCode.NRefactory.CSharp
newField.AddChild (variable, Roles.Variable); newField.AddChild (variable, Roles.Variable);
} }
} }
if (location != null) if (location != null &&location.Count > locationIdx)
newField.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.Semicolon); newField.AddChild (new CSharpTokenNode (Convert (location [locationIdx++])), Roles.Semicolon);
typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole); typeStack.Peek ().AddChild (newField, Roles.TypeMemberRole);
} }
@ -1568,6 +1580,9 @@ namespace ICSharpCode.NRefactory.CSharp
var expr = statementErrorExpression.Expr.Accept (this) as Expression; var expr = statementErrorExpression.Expr.Accept (this) as Expression;
if (expr != null) if (expr != null)
result.AddChild ((Expression)expr, Roles.Expression); result.AddChild ((Expression)expr, Roles.Expression);
var location = LocationsBag.GetLocations (statementErrorExpression);
if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Semicolon);
return result; return result;
} }
@ -2379,7 +2394,9 @@ namespace ICSharpCode.NRefactory.CSharp
if (binaryExpression.Left != null) if (binaryExpression.Left != null)
result.AddChild ((Expression)binaryExpression.Left.Accept (this), BinaryOperatorExpression.LeftRole); 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) if (binaryExpression.Right != null)
result.AddChild ((Expression)binaryExpression.Right.Accept (this), BinaryOperatorExpression.RightRole); result.AddChild ((Expression)binaryExpression.Right.Accept (this), BinaryOperatorExpression.RightRole);
return result; return result;
@ -2391,7 +2408,9 @@ namespace ICSharpCode.NRefactory.CSharp
result.Operator = BinaryOperatorType.NullCoalescing; result.Operator = BinaryOperatorType.NullCoalescing;
if (nullCoalescingOperator.LeftExpression != null) if (nullCoalescingOperator.LeftExpression != null)
result.AddChild ((Expression)nullCoalescingOperator.LeftExpression.Accept (this), BinaryOperatorExpression.LeftRole); 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) if (nullCoalescingOperator.RightExpression != null)
result.AddChild ((Expression)nullCoalescingOperator.RightExpression.Accept (this), BinaryOperatorExpression.RightRole); result.AddChild ((Expression)nullCoalescingOperator.RightExpression.Accept (this), BinaryOperatorExpression.RightRole);
return result; return result;
@ -2684,25 +2703,31 @@ namespace ICSharpCode.NRefactory.CSharp
public override object Visit (NewAnonymousType newAnonymousType) public override object Visit (NewAnonymousType newAnonymousType)
{ {
var result = new AnonymousTypeCreateExpression (); var result = new AnonymousTypeCreateExpression ();
if (newAnonymousType.Parameters == null) var location = LocationsBag.GetLocations (newAnonymousType);
return result; result.AddChild (new CSharpTokenNode (Convert (newAnonymousType.Location)), ObjectCreateExpression.NewKeywordRole);
if (location != null)
result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.LBrace);
if (newAnonymousType.Parameters != null) {
foreach (var par in newAnonymousType.Parameters) { foreach (var par in newAnonymousType.Parameters) {
if (par == null) if (par == null)
continue; continue;
var location = LocationsBag.GetLocations (par); var parLocation = LocationsBag.GetLocations (par);
if (location == null) { if (parLocation == null) {
if (par.Expr != null) if (par.Expr != null)
result.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression); result.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression);
} else { } else {
var namedExpression = new NamedExpression (); var namedExpression = new NamedExpression ();
namedExpression.AddChild (Identifier.Create (par.Name, Convert (par.Location)), Roles.Identifier); namedExpression.AddChild (Identifier.Create (par.Name, Convert (par.Location)), Roles.Identifier);
namedExpression.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Assign); namedExpression.AddChild (new CSharpTokenNode (Convert (parLocation [0])), Roles.Assign);
if (par.Expr != null) if (par.Expr != null)
namedExpression.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression); namedExpression.AddChild ((Expression)par.Expr.Accept (this), Roles.Expression);
result.AddChild (namedExpression, Roles.Expression); result.AddChild (namedExpression, Roles.Expression);
} }
} }
}
if (location != null && location.Count > 1)
result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.RBrace);
return result; return result;
} }
@ -2725,34 +2750,50 @@ namespace ICSharpCode.NRefactory.CSharp
foreach (var expr in minit.Initializers) { foreach (var expr in minit.Initializers) {
var collectionInit = expr as CollectionElementInitializer; var collectionInit = expr as CollectionElementInitializer;
if (collectionInit != null) { if (collectionInit != null) {
var parent = new ArrayInitializerExpression (); AstNode parent;
// For ease of use purposes in the resolver the ast representation
parent.AddChild (new CSharpTokenNode (Convert (expr.Location)), Roles.LBrace); // of { a, b, c } is { {a}, {b}, {c} } - but the generated ArrayInitializerExpression
// can be identified by expr.IsSingleElement.
if (!collectionInit.IsSingle) {
parent = new ArrayInitializerExpression();
parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location)), Roles.LBrace);
} else {
parent = ArrayInitializerExpression.CreateSingleElementInitializer ();
}
for (int i = 0; i < collectionInit.Arguments.Count; i++) { for (int i = 0; i < collectionInit.Arguments.Count; i++) {
var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument; var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument;
if (arg == null) if (arg == null)
continue; continue;
parent.AddChild ((ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept (this), Roles.Expression); parent.AddChild(
(ICSharpCode.NRefactory.CSharp.Expression)arg.Expr.Accept(this),
Roles.Expression
);
} }
if (!collectionInit.IsSingle) {
var braceLocs = LocationsBag.GetLocations(expr); var braceLocs = LocationsBag.GetLocations(expr);
if (braceLocs != null) if (braceLocs != null)
parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0])), Roles.RBrace); parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0])), Roles.RBrace);
}
init.AddChild (parent, Roles.Expression); init.AddChild((ArrayInitializerExpression)parent, Roles.Expression);
} else { } else {
var eleInit = expr as ElementInitializer; var eleInit = expr as ElementInitializer;
if (eleInit != null) { if (eleInit != null) {
var nexpr = new NamedExpression(); var nexpr = new NamedExpression();
nexpr.AddChild (Identifier.Create (eleInit.Name, Convert (eleInit.Location)), Roles.Identifier); nexpr.AddChild(
Identifier.Create(eleInit.Name, Convert(eleInit.Location)),
Roles.Identifier
);
var assignLoc = LocationsBag.GetLocations(eleInit); var assignLoc = LocationsBag.GetLocations(eleInit);
if (assignLoc != null) if (assignLoc != null)
nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0])), Roles.Assign); nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0])), Roles.Assign);
if (eleInit.Source != null) { if (eleInit.Source != null) {
if (eleInit.Source is CollectionOrObjectInitializers) { if (eleInit.Source is CollectionOrObjectInitializers) {
var arrInit = new ArrayInitializerExpression(); var arrInit = new ArrayInitializerExpression();
AddConvertCollectionOrObjectInitializers (arrInit, eleInit.Source as CollectionOrObjectInitializers); AddConvertCollectionOrObjectInitializers(
arrInit,
eleInit.Source as CollectionOrObjectInitializers
);
nexpr.AddChild(arrInit, Roles.Expression); nexpr.AddChild(arrInit, Roles.Expression);
} else { } else {
nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression); nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression);
@ -2764,8 +2805,8 @@ namespace ICSharpCode.NRefactory.CSharp
} }
if (commaLoc != null && curComma < commaLoc.Count) if (commaLoc != null && curComma < commaLoc.Count)
init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++])), Roles.Comma); init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++])), Roles.Comma);
} }
if (initLoc != null) { if (initLoc != null) {
if (initLoc.Count == 3) // optional comma if (initLoc.Count == 3) // optional comma
init.AddChild(new CSharpTokenNode(Convert(initLoc [1])), Roles.Comma); init.AddChild(new CSharpTokenNode(Convert(initLoc [1])), Roles.Comma);
@ -2773,6 +2814,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public override object Visit (NewInitialize newInitializeExpression) public override object Visit (NewInitialize newInitializeExpression)
{ {
var result = new ObjectCreateExpression (); var result = new ObjectCreateExpression ();
@ -2833,7 +2875,7 @@ namespace ICSharpCode.NRefactory.CSharp
next = next.Next; next = next.Next;
} }
if (arrayCreationExpression.Initializers != null && arrayCreationExpression.Initializers.Count != 0) { if (arrayCreationExpression.Initializers != null) {
var initLocation = LocationsBag.GetLocations (arrayCreationExpression.Initializers); var initLocation = LocationsBag.GetLocations (arrayCreationExpression.Initializers);
ArrayInitializerExpression initializer = new ArrayInitializerExpression (); ArrayInitializerExpression initializer = new ArrayInitializerExpression ();
@ -2848,9 +2890,11 @@ namespace ICSharpCode.NRefactory.CSharp
initializer.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma); initializer.AddChild (new CSharpTokenNode (Convert (commaLocations [i])), Roles.Comma);
} }
} }
if (initLocation != null) {
if (initLocation != null) if (initLocation.Count == 2) // optional comma
initializer.AddChild (new CSharpTokenNode(Convert(initLocation [0])), Roles.Comma);
initializer.AddChild (new CSharpTokenNode (Convert (initLocation [initLocation.Count - 1])), Roles.RBrace); initializer.AddChild (new CSharpTokenNode (Convert (initLocation [initLocation.Count - 1])), Roles.RBrace);
}
result.AddChild (initializer, ArrayCreateExpression.InitializerRole); result.AddChild (initializer, ArrayCreateExpression.InitializerRole);
} }
@ -3042,7 +3086,9 @@ namespace ICSharpCode.NRefactory.CSharp
result.Operator = AssignmentOperatorType.Assign; result.Operator = AssignmentOperatorType.Assign;
if (simpleAssign.Target != null) if (simpleAssign.Target != null)
result.AddChild ((Expression)simpleAssign.Target.Accept (this), AssignmentExpression.LeftRole); 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) { if (simpleAssign.Source != null) {
result.AddChild ((Expression)simpleAssign.Source.Accept (this), AssignmentExpression.RightRole); result.AddChild ((Expression)simpleAssign.Source.Accept (this), AssignmentExpression.RightRole);
} }
@ -3087,7 +3133,9 @@ namespace ICSharpCode.NRefactory.CSharp
if (compoundAssign.Target != null) if (compoundAssign.Target != null)
result.AddChild ((Expression)compoundAssign.Target.Accept (this), AssignmentExpression.LeftRole); 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) if (compoundAssign.Source != null)
result.AddChild ((Expression)compoundAssign.Source.Accept (this), AssignmentExpression.RightRole); result.AddChild ((Expression)compoundAssign.Source.Accept (this), AssignmentExpression.RightRole);
return result; return result;
@ -3173,7 +3221,7 @@ namespace ICSharpCode.NRefactory.CSharp
if (location != null) { if (location != null) {
if (location.Count == 2) // optional comma if (location.Count == 2) // optional comma
result.AddChild (new CSharpTokenNode (Convert (location [1])), Roles.Comma); result.AddChild (new CSharpTokenNode (Convert (location [0])), Roles.Comma);
result.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.RBrace); result.AddChild (new CSharpTokenNode (Convert (location [location.Count - 1])), Roles.RBrace);
} }
return result; return result;
@ -3182,8 +3230,13 @@ namespace ICSharpCode.NRefactory.CSharp
#endregion #endregion
#region LINQ expressions #region LINQ expressions
QueryOrderClause currentQueryOrderClause;
public override object Visit (Mono.CSharp.Linq.QueryExpression queryExpression) public override object Visit (Mono.CSharp.Linq.QueryExpression queryExpression)
{ {
var oldQueryOrderClause = currentQueryOrderClause;
try {
currentQueryOrderClause = null;
var result = new QueryExpression (); var result = new QueryExpression ();
var currentClause = queryExpression.next; var currentClause = queryExpression.next;
@ -3196,12 +3249,18 @@ namespace ICSharpCode.NRefactory.CSharp
// create a new QueryExpression for the remaining query // create a new QueryExpression for the remaining query
result = new QueryExpression (); result = new QueryExpression ();
} }
if (clause != null) {
result.AddChild (clause, QueryExpression.ClauseRole); result.AddChild (clause, QueryExpression.ClauseRole);
}
currentClause = currentClause.next; currentClause = currentClause.next;
} }
return result; return result;
} }
finally {
currentQueryOrderClause = oldQueryOrderClause;
}
}
public override object Visit (Mono.CSharp.Linq.QueryStartClause queryStart) public override object Visit (Mono.CSharp.Linq.QueryStartClause queryStart)
{ {
@ -3366,7 +3425,7 @@ namespace ICSharpCode.NRefactory.CSharp
public override object Visit (Mono.CSharp.Linq.OrderByAscending orderByAscending) public override object Visit (Mono.CSharp.Linq.OrderByAscending orderByAscending)
{ {
var result = new QueryOrderClause (); currentQueryOrderClause = new QueryOrderClause();
var ordering = new QueryOrdering (); var ordering = new QueryOrdering ();
if (orderByAscending.Expr != null) if (orderByAscending.Expr != null)
@ -3376,13 +3435,13 @@ namespace ICSharpCode.NRefactory.CSharp
ordering.Direction = QueryOrderingDirection.Ascending; ordering.Direction = QueryOrderingDirection.Ascending;
ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole); ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole);
} }
result.AddChild (ordering, QueryOrderClause.OrderingRole); currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole);
return result; return currentQueryOrderClause;
} }
public override object Visit (Mono.CSharp.Linq.OrderByDescending orderByDescending) public override object Visit (Mono.CSharp.Linq.OrderByDescending orderByDescending)
{ {
var result = new QueryOrderClause (); currentQueryOrderClause = new QueryOrderClause ();
var ordering = new QueryOrdering (); var ordering = new QueryOrdering ();
if (orderByDescending.Expr != null) if (orderByDescending.Expr != null)
@ -3392,14 +3451,12 @@ namespace ICSharpCode.NRefactory.CSharp
ordering.Direction = QueryOrderingDirection.Descending; ordering.Direction = QueryOrderingDirection.Descending;
ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole); ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole);
} }
result.AddChild (ordering, QueryOrderClause.OrderingRole); currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole);
return result; return currentQueryOrderClause;
} }
public override object Visit (Mono.CSharp.Linq.ThenByAscending thenByAscending) public override object Visit (Mono.CSharp.Linq.ThenByAscending thenByAscending)
{ {
var result = new QueryOrderClause ();
var ordering = new QueryOrdering (); var ordering = new QueryOrdering ();
if (thenByAscending.Expr != null) if (thenByAscending.Expr != null)
ordering.AddChild ((Expression)thenByAscending.Expr.Accept (this), Roles.Expression); ordering.AddChild ((Expression)thenByAscending.Expr.Accept (this), Roles.Expression);
@ -3408,14 +3465,12 @@ namespace ICSharpCode.NRefactory.CSharp
ordering.Direction = QueryOrderingDirection.Ascending; ordering.Direction = QueryOrderingDirection.Ascending;
ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole); ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.AscendingKeywordRole);
} }
result.AddChild (ordering, QueryOrderClause.OrderingRole); currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole);
return result; return null;
} }
public override object Visit (Mono.CSharp.Linq.ThenByDescending thenByDescending) public override object Visit (Mono.CSharp.Linq.ThenByDescending thenByDescending)
{ {
var result = new QueryOrderClause ();
var ordering = new QueryOrdering (); var ordering = new QueryOrdering ();
if (thenByDescending.Expr != null) if (thenByDescending.Expr != null)
ordering.AddChild ((Expression)thenByDescending.Expr.Accept (this), Roles.Expression); ordering.AddChild ((Expression)thenByDescending.Expr.Accept (this), Roles.Expression);
@ -3424,8 +3479,8 @@ namespace ICSharpCode.NRefactory.CSharp
ordering.Direction = QueryOrderingDirection.Descending; ordering.Direction = QueryOrderingDirection.Descending;
ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole); ordering.AddChild (new CSharpTokenNode (Convert (location [0])), QueryOrdering.DescendingKeywordRole);
} }
result.AddChild (ordering, QueryOrderClause.OrderingRole); currentQueryOrderClause.AddChild (ordering, QueryOrderClause.OrderingRole);
return result; return null;
} }
public override object Visit (Await awaitExpr) public override object Visit (Await awaitExpr)
@ -3438,17 +3493,83 @@ namespace ICSharpCode.NRefactory.CSharp
return result; return result;
} }
#endregion #endregion
#region XmlDoc
public DocumentationReference ConvertXmlDoc(DocumentationBuilder doc)
{
DocumentationReference result = new DocumentationReference();
if (doc.ParsedName != null) {
if (doc.ParsedName.Name == "<this>") {
result.EntityType = EntityType.Indexer;
} else {
result.MemberName = doc.ParsedName.Name;
}
if (doc.ParsedName.Left != null) {
result.DeclaringType = ConvertToType(doc.ParsedName.Left);
} else if (doc.ParsedBuiltinType != null) {
result.DeclaringType = ConvertToType(doc.ParsedBuiltinType);
}
if (doc.ParsedName.TypeParameters != null) {
for (int i = 0; i < doc.ParsedName.TypeParameters.Count; i++) {
result.TypeArguments.Add(ConvertToType(doc.ParsedName.TypeParameters[i]));
}
}
} else if (doc.ParsedBuiltinType != null) {
result.EntityType = EntityType.TypeDefinition;
result.DeclaringType = ConvertToType(doc.ParsedBuiltinType);
}
if (doc.ParsedParameters != null) {
result.HasParameterList = true;
result.Parameters.AddRange(doc.ParsedParameters.Select(ConvertXmlDocParameter));
}
if (doc.ParsedOperator != null) {
result.EntityType = EntityType.Operator;
result.OperatorType = (OperatorType)doc.ParsedOperator;
if (result.OperatorType == OperatorType.Implicit || result.OperatorType == OperatorType.Explicit) {
var returnTypeParam = result.Parameters.LastOrNullObject();
returnTypeParam.Remove(); // detach from parameter list
var returnType = returnTypeParam.Type;
returnType.Remove();
result.ConversionOperatorReturnType = returnType;
}
if (result.Parameters.Count == 0) {
// reset HasParameterList if necessary
result.HasParameterList = false;
}
}
return result;
}
ParameterDeclaration ConvertXmlDocParameter(DocumentationParameter p)
{
ParameterDeclaration result = new ParameterDeclaration();
switch (p.Modifier) {
case Parameter.Modifier.OUT:
result.ParameterModifier = ParameterModifier.Out;
break;
case Parameter.Modifier.REF:
result.ParameterModifier = ParameterModifier.Ref;
break;
case Parameter.Modifier.PARAMS:
result.ParameterModifier = ParameterModifier.Params;
break;
}
if (p.Type != null) {
result.Type = ConvertToType(p.Type);
}
return result;
}
#endregion
} }
public CSharpParser () public CSharpParser ()
{ {
CompilerSettings = new CompilerSettings (); compilerSettings = new CompilerSettings();
CompilerSettings.Unsafe = true;
} }
public CSharpParser (CompilerSettings args) public CSharpParser (CompilerSettings args)
{ {
CompilerSettings = args; compilerSettings = args ?? new CompilerSettings();
} }
static AstNode GetOuterLeft (AstNode node) static AstNode GetOuterLeft (AstNode node)
@ -3569,6 +3690,7 @@ namespace ICSharpCode.NRefactory.CSharp
} }
ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter (null); ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter (null);
[Obsolete("Use the Errors/Warnings/ErrorsAndWarnings properties instead")]
public ErrorReportPrinter ErrorPrinter { public ErrorReportPrinter ErrorPrinter {
get { get {
return errorReportPrinter; return errorReportPrinter;
@ -3587,28 +3709,50 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
public CompilationUnit Parse (ITextSource textSource, string fileName, int lineModifier = 0) public IEnumerable<Error> Errors {
{ get {
return Parse (textSource.CreateReader (), fileName, lineModifier); return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Error);
}
} }
public CompilationUnit Parse (TextReader reader, string fileName, int lineModifier = 0) public IEnumerable<Error> Warnings {
{ get {
// TODO: can we optimize this to avoid the text->stream->text roundtrip? return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Warning);
using (MemoryStream stream = new MemoryStream ()) { }
StreamWriter w = new StreamWriter (stream, Encoding.UTF8); }
char[] buffer = new char[2048];
int read; public IEnumerable<Error> ErrorsAndWarnings {
while ((read = reader.ReadBlock(buffer, 0, buffer.Length)) > 0) get { return errorReportPrinter.Errors; }
w.Write (buffer, 0, read); }
w.Flush (); // we can't close the StreamWriter because that would also close the MemoryStream
stream.Position = 0;
return Parse (stream, fileName, lineModifier); /// <summary>
/// Parses a C# code file.
/// </summary>
/// <param name="program">The source code to parse.</param>
/// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
/// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
/// <returns>Returns the syntax tree.</returns>
public SyntaxTree Parse (string program, string fileName = "")
{
return Parse (new StringTextSource (program), fileName);
} }
/// <summary>
/// Parses a C# code file.
/// </summary>
/// <param name="reader">The text reader containing the source code to parse.</param>
/// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
/// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
/// <returns>Returns the syntax tree.</returns>
public SyntaxTree Parse (TextReader reader, string fileName = "")
{
return Parse(new StringTextSource (reader.ReadToEnd ()), fileName);
} }
public CompilationUnit Parse(CompilerCompilationUnit top, string fileName, int lineModifier = 0) /// <summary>
/// Converts a Mono.CSharp syntax tree into an NRefactory syntax tree.
/// </summary>
public SyntaxTree Parse(CompilerCompilationUnit top, string fileName)
{ {
if (top == null) { if (top == null) {
return null; return null;
@ -3622,116 +3766,227 @@ namespace ICSharpCode.NRefactory.CSharp
if (top.LastYYValue is Mono.CSharp.Expression) { if (top.LastYYValue is Mono.CSharp.Expression) {
conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode; conversionVisitor.Unit.TopExpression = ((Mono.CSharp.Expression)top.LastYYValue).Accept(conversionVisitor) as AstNode;
} }
conversionVisitor.Unit.FileName = fileName; conversionVisitor.Unit.FileName = fileName;
conversionVisitor.Unit.ConditionalSymbols = top.Conditionals.Concat (compilerSettings.ConditionalSymbols).ToArray ();
return conversionVisitor.Unit; return conversionVisitor.Unit;
} }
public CompilerSettings CompilerSettings { public CompilerSettings CompilerSettings {
get; get { return compilerSettings; }
internal set; set {
if (value == null)
throw new ArgumentNullException();
compilerSettings = value;
}
} }
/// <summary>
/// Callback that gets called with the Mono.CSharp syntax tree whenever some code is parsed.
/// </summary>
public Action<CompilerCompilationUnit> CompilationUnitCallback { public Action<CompilerCompilationUnit> CompilationUnitCallback {
get; get;
set; set;
} }
/// <summary>
/// Specifies whether to run the parser in a special mode for generating the type system.
/// If this property is true, the syntax tree will only contain nodes relevant for the
/// <see cref="SyntaxTree.ToTypeSystem()"/> call and might be missing other nodes (e.g. method bodies).
/// The default is false.
/// </summary>
public bool GenerateTypeSystemMode { public bool GenerateTypeSystemMode {
get; get;
set; set;
} }
public CompilationUnit Parse (string program, string fileName) TextLocation initialLocation = new TextLocation(1, 1);
{
return Parse (new StringReader (program), fileName); /// <summary>
/// Specifies the text location where parsing starts.
/// This property can be used when parsing a part of a file to make the locations of the AstNodes
/// refer to the position in the whole file.
/// The default is (1,1).
/// </summary>
public TextLocation InitialLocation {
get { return initialLocation; }
set { initialLocation = value; }
} }
internal static object parseLock = new object (); internal static object parseLock = new object ();
public CompilationUnit Parse(Stream stream, string fileName, int lineModifier = 0) /// <summary>
/// Parses a C# code file.
/// </summary>
/// <param name="stream">The stream containing the source code to parse.</param>
/// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
/// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
/// <returns>Returns the syntax tree.</returns>
public SyntaxTree Parse (Stream stream, string fileName = "")
{
return Parse (new StreamReader (stream), fileName);
}
/// <summary>
/// Parses a C# code file.
/// </summary>
/// <param name="program">The source code to parse.</param>
/// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
/// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
/// </param>
/// <returns>Returns the syntax tree.</returns>
public SyntaxTree Parse(ITextSource program, string fileName = "")
{
return Parse(program, fileName, initialLocation.Line, initialLocation.Column);
}
SyntaxTree Parse(ITextSource program, string fileName, int initialLine, int initialColumn)
{ {
lock (parseLock) { lock (parseLock) {
errorReportPrinter = new ErrorReportPrinter (""); errorReportPrinter = new ErrorReportPrinter ("");
var ctx = new CompilerContext (CompilerSettings, errorReportPrinter); var ctx = new CompilerContext (compilerSettings.ToMono(), errorReportPrinter);
ctx.Settings.TabSize = 1; ctx.Settings.TabSize = 1;
var reader = new SeekableStreamReader (stream, Encoding.UTF8); var reader = new SeekableStreamReader (program);
var file = new SourceFile (fileName, fileName, 0); var file = new SourceFile (fileName, fileName, 0);
Location.Initialize (new List<SourceFile> (new [] { file })); Location.Initialize (new List<SourceFile> (new [] { file }));
var module = new ModuleContainer (ctx); 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, initialLine - 1, initialColumn - 1);
var top = new CompilerCompilationUnit () { var top = new CompilerCompilationUnit () {
ModuleCompiled = module, ModuleCompiled = module,
LocationsBag = parser.LocationsBag, LocationsBag = session.LocationsBag,
SpecialsBag = parser.Lexer.sbag SpecialsBag = parser.Lexer.sbag,
Conditionals = parser.Lexer.SourceFile.Conditionals
}; };
var unit = Parse (top, fileName, lineModifier); var unit = Parse (top, fileName);
unit.Errors.AddRange (errorReportPrinter.Errors); unit.Errors.AddRange (errorReportPrinter.Errors);
CompilerCallableEntryPoint.Reset (); CompilerCallableEntryPoint.Reset ();
return unit; return unit;
} }
} }
public IEnumerable<EntityDeclaration> ParseTypeMembers (TextReader reader, int lineModifier = 0) public IEnumerable<EntityDeclaration> ParseTypeMembers (string code)
{
return ParseTypeMembers(code, initialLocation.Line, initialLocation.Column);
}
IEnumerable<EntityDeclaration> ParseTypeMembers (string code, int initialLine, int initialColumn)
{ {
string code = "unsafe partial class MyClass { " + Environment.NewLine + reader.ReadToEnd () + "}"; const string prefix = "unsafe partial class MyClass { ";
var cu = Parse (new StringReader (code), "parsed.cs", lineModifier - 1); var syntaxTree = Parse (new StringTextSource (prefix + code + "}"), "parsed.cs", initialLine, initialColumn - prefix.Length);
if (cu == null) if (syntaxTree == null)
return Enumerable.Empty<EntityDeclaration> (); return Enumerable.Empty<EntityDeclaration> ();
var td = cu.Children.FirstOrDefault () as TypeDeclaration; var td = syntaxTree.FirstChild as TypeDeclaration;
if (td != null) if (td != null) {
return td.Members; var members = td.Members.ToArray();
// detach members from parent
foreach (var m in members)
m.Remove();
return members;
}
return Enumerable.Empty<EntityDeclaration> (); return Enumerable.Empty<EntityDeclaration> ();
} }
public IEnumerable<Statement> ParseStatements (TextReader reader, int lineModifier = 0) public IEnumerable<Statement> ParseStatements (string code)
{ {
string code = "void M() { " + Environment.NewLine + reader.ReadToEnd () + "}"; return ParseStatements(code, initialLocation.Line, initialLocation.Column);
var members = ParseTypeMembers (new StringReader (code), lineModifier - 1); }
IEnumerable<Statement> ParseStatements (string code, int initialLine, int initialColumn)
{
// the dummy method is async so that 'await' expressions are parsed as expected
const string prefix = "async void M() { ";
var members = ParseTypeMembers (prefix + code + "}", initialLine, initialColumn - prefix.Length);
var method = members.FirstOrDefault () as MethodDeclaration; var method = members.FirstOrDefault () as MethodDeclaration;
if (method != null && method.Body != null) if (method != null && method.Body != null) {
return method.Body.Statements; var statements = method.Body.Statements.ToArray();
// detach statements from parent
foreach (var st in statements)
st.Remove();
return statements;
}
return Enumerable.Empty<Statement> (); return Enumerable.Empty<Statement> ();
} }
public AstType ParseTypeReference (TextReader reader) public AstType ParseTypeReference (string code)
{ {
string code = reader.ReadToEnd () + " a;"; var members = ParseTypeMembers (code + " a;");
var members = ParseTypeMembers (new StringReader (code));
var field = members.FirstOrDefault () as FieldDeclaration; var field = members.FirstOrDefault () as FieldDeclaration;
if (field != null) if (field != null) {
return field.ReturnType; AstType type = field.ReturnType;
type.Remove();
return type;
}
return AstType.Null; return AstType.Null;
} }
public AstNode ParseExpression (TextReader reader) public Expression ParseExpression (string code)
{ {
var es = ParseStatements (new StringReader ("tmp = " + Environment.NewLine + reader.ReadToEnd () + ";"), -1).FirstOrDefault () as ExpressionStatement; const string prefix = "tmp = ";
var statements = ParseStatements (prefix + code + ";", initialLocation.Line, initialLocation.Column - prefix.Length);
var es = statements.FirstOrDefault () as ExpressionStatement;
if (es != null) { if (es != null) {
AssignmentExpression ae = es.Expression as AssignmentExpression; AssignmentExpression ae = es.Expression as AssignmentExpression;
if (ae != null) if (ae != null) {
return ae.Right; Expression expr = ae.Right;
expr.Remove();
return expr;
} }
return null; }
return Expression.Null;
} }
/*
/// <summary> /// <summary>
/// Parses a file snippet; guessing what the code snippet represents (compilation unit, type members, block, type reference, expression). /// Parses a file snippet; guessing what the code snippet represents (whole file, type members, block, type reference, expression).
/// </summary> /// </summary>
public AstNode ParseSnippet (TextReader reader) public AstNode ParseSnippet (string code)
{ {
// TODO: add support for parsing a part of a file // TODO: add support for parsing a part of a file
throw new NotImplementedException (); throw new NotImplementedException ();
} }
*/
public DocumentationReference ParseDocumentationReference (string cref) public DocumentationReference ParseDocumentationReference (string cref)
{ {
// see Mono.CSharp.DocumentationBuilder.HandleXrefCommon
if (cref == null) if (cref == null)
throw new ArgumentNullException ("cref"); throw new ArgumentNullException ("cref");
// Additional symbols for < and > are allowed for easier XML typing
cref = cref.Replace ('{', '<').Replace ('}', '>'); cref = cref.Replace ('{', '<').Replace ('}', '>');
// TODO: add support for parsing cref attributes
// (documentation_parsing production, see DocumentationBuilder.HandleXrefCommon) lock (parseLock) {
throw new NotImplementedException (); errorReportPrinter = new ErrorReportPrinter("");
var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter);
ctx.Settings.TabSize = 1;
var reader = new SeekableStreamReader(new StringTextSource (cref));
var file = new SourceFile("", "", 0);
Location.Initialize(new List<SourceFile> (new [] { file }));
var module = new ModuleContainer(ctx);
module.DocumentationBuilder = new DocumentationBuilder(module);
var source_file = new CompilationSourceFile (module);
var report = new Report (ctx, errorReportPrinter);
ParserSession session = new ParserSession ();
session.LocationsBag = new LocationsBag ();
var parser = new Mono.CSharp.CSharpParser (reader, source_file, report, session);
parser.Lexer.Line += initialLocation.Line - 1;
parser.Lexer.Column += initialLocation.Column - 1;
parser.Lexer.putback_char = Tokenizer.DocumentationXref;
parser.Lexer.parsing_generic_declaration_doc = true;
parser.parse ();
if (report.Errors > 0) {
// Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
// mc.GetSignatureForError (), cref);
}
ConversionVisitor conversionVisitor = new ConversionVisitor (false, session.LocationsBag);
DocumentationReference docRef = conversionVisitor.ConvertXmlDoc(module.DocumentationBuilder);
CompilerCallableEntryPoint.Reset();
return docRef;
}
} }
} }
} }

151
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/CompilerSettings.cs

@ -0,0 +1,151 @@
// 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.Implementation;
namespace ICSharpCode.NRefactory.CSharp
{
/// <summary>
/// C# compiler settings.
/// </summary>
[Serializable]
public class CompilerSettings : AbstractFreezable
{
protected override void FreezeInternal()
{
conditionalSymbols = FreezableHelper.FreezeList(conditionalSymbols);
specificWarningsAsErrors = FreezableHelper.FreezeList(specificWarningsAsErrors);
disabledWarnings = FreezableHelper.FreezeList(disabledWarnings);
base.FreezeInternal();
}
/// <summary>
/// Creates a new CompilerSettings instance.
/// </summary>
public CompilerSettings()
{
}
bool allowUnsafeBlocks = true;
/// <summary>
/// Gets/Sets whether <c>unsafe</c> code is allowed.
/// The default is <c>true</c>. If set to false, parsing unsafe code will result in parser errors.
/// </summary>
public bool AllowUnsafeBlocks {
get { return allowUnsafeBlocks; }
set {
FreezableHelper.ThrowIfFrozen(this);
allowUnsafeBlocks = value;
}
}
bool checkForOverflow;
/// <summary>
/// Gets/Sets whether overflow checking is enabled.
/// The default is <c>false</c>. This setting effects semantic analysis.
/// </summary>
public bool CheckForOverflow {
get { return checkForOverflow; }
set { checkForOverflow = value; }
}
Version languageVersion = new Version((int)Mono.CSharp.LanguageVersion.Default, 0);
/// <summary>
/// Gets/Sets the language version used by the parser.
/// Using language constructs newer than the supplied version will result in parser errors.
/// </summary>
public Version LanguageVersion {
get { return languageVersion; }
set {
FreezableHelper.ThrowIfFrozen(this);
if (value == null)
throw new ArgumentNullException();
languageVersion = value;
}
}
IList<string> conditionalSymbols = new List<string>();
/// <summary>
/// Gets/Sets the list of conditional symbols that are defined project-wide.
/// </summary>
public IList<string> ConditionalSymbols {
get { return conditionalSymbols; }
}
bool treatWarningsAsErrors;
public bool TreatWarningsAsErrors {
get { return treatWarningsAsErrors; }
set {
FreezableHelper.ThrowIfFrozen(this);
treatWarningsAsErrors = value;
}
}
IList<int> specificWarningsAsErrors = new List<int>();
/// <summary>
/// Allows treating specific warnings as errors without setting <see cref="TreatWarningsAsErrors"/> to true.
/// </summary>
public IList<int> SpecificWarningsAsErrors {
get { return specificWarningsAsErrors; }
}
int warningLevel = 4;
public int WarningLevel {
get { return warningLevel; }
set {
FreezableHelper.ThrowIfFrozen(this);
warningLevel = value;
}
}
IList<int> disabledWarnings = new List<int>();
/// <summary>
/// Allows treating specific warnings as errors without setting <see cref="TreatWarningsAsErrors"/> to true.
/// </summary>
public IList<int> DisabledWarnings {
get { return disabledWarnings; }
}
internal Mono.CSharp.CompilerSettings ToMono()
{
var s = new Mono.CSharp.CompilerSettings();
s.Unsafe = allowUnsafeBlocks;
s.Checked = checkForOverflow;
s.Version = (Mono.CSharp.LanguageVersion)languageVersion.Major;
s.WarningsAreErrors = treatWarningsAsErrors;
s.WarningLevel = warningLevel;
foreach (int code in disabledWarnings)
s.SetIgnoreWarning(code);
foreach (int code in specificWarningsAsErrors)
s.AddWarningAsError(code);
foreach (string sym in conditionalSymbols)
s.AddConditionalSymbol(sym);
return s;
}
}
}

103
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/SeekableStreamReader.cs

@ -0,0 +1,103 @@
//
// SeekableStreamReader.cs
//
// Author:
// Mike Krüger <mkrueger@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://xamarin.com)
//
// 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 ICSharpCode.NRefactory.Editor;
using System.IO;
using System.Text;
namespace Mono.CSharp
{
public class SeekableStreamReader : IDisposable
{
public const int DefaultReadAheadSize = 2048;
readonly ITextSource textSource;
int pos;
static string GetAllText(Stream stream, Encoding encoding) {
using (var rdr = new StreamReader(stream, encoding)) {
return rdr.ReadToEnd();
}
}
public SeekableStreamReader (Stream stream, Encoding encoding, char[] sharedBuffer = null) : this(new StringTextSource(GetAllText(stream, encoding)))
{
}
public SeekableStreamReader (ITextSource source)
{
this.textSource = source;
}
public void Dispose ()
{
}
/// <remarks>
/// This value corresponds to the current position in a stream of characters.
/// The StreamReader hides its manipulation of the underlying byte stream and all
/// character set/decoding issues. Thus, we cannot use this position to guess at
/// the corresponding position in the underlying byte stream even though there is
/// a correlation between them.
/// </remarks>
public int Position {
get {
return pos;
}
set {
pos = value;
}
}
public char GetChar (int position)
{
return textSource.GetCharAt (position);
}
public char[] ReadChars (int fromPosition, int toPosition)
{
return textSource.GetText (fromPosition, toPosition - fromPosition).ToCharArray ();
}
public int Peek ()
{
if (pos >= textSource.TextLength)
return -1;
return textSource.GetCharAt (pos);
}
public int Read ()
{
if (pos >= textSource.TextLength)
return -1;
return textSource.GetCharAt (pos++);
}
}
}

2
NRefactory/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) public MyBinaryWriter (Stream stream)
: base (stream) : base (stream)

73
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs

@ -183,6 +183,7 @@ namespace Mono.CompilerServices.SymbolWriter
{ {
#region This is actually written to the symbol file #region This is actually written to the symbol file
public readonly int Row; public readonly int Row;
public int Column;
public readonly int File; public readonly int File;
public readonly int Offset; public readonly int Offset;
public readonly bool IsHidden; // Obsolete is never used public readonly bool IsHidden; // Obsolete is never used
@ -195,28 +196,35 @@ namespace Mono.CompilerServices.SymbolWriter
public int Compare (LineNumberEntry l1, LineNumberEntry l2) public int Compare (LineNumberEntry l1, LineNumberEntry l2)
{ {
return l1.Row == l2.Row ? return l1.Row == l2.Row ?
l1.Offset.CompareTo (l2.Offset) : l1.Column.CompareTo (l2.Column) :
l1.Row.CompareTo (l2.Row); 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) 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.File = file;
this.Row = row; this.Row = row;
this.Column = column;
this.Offset = offset; this.Offset = offset;
this.IsHidden = is_hidden; this.IsHidden = is_hidden;
} }
public override string ToString () 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; creating = true;
} }
public SourceFileEntry (MonoSymbolFile file, string file_name, public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum)
byte[] guid, byte[] checksum)
: this (file, file_name) : this (file, file_name)
{ {
this.guid = guid; this.guid = guid;
@ -694,8 +701,10 @@ namespace Mono.CompilerServices.SymbolWriter
DataOffset = (int) bw.BaseStream.Position; DataOffset = (int) bw.BaseStream.Position;
bw.Write (file_name); bw.Write (file_name);
if (guid == null) { if (guid == null)
guid = Guid.NewGuid ().ToByteArray (); guid = new byte[16];
if (hash == null) {
try { try {
using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) { using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
MD5 md5 = MD5.Create (); MD5 md5 = MD5.Create ();
@ -791,7 +800,6 @@ namespace Mono.CompilerServices.SymbolWriter
public const int Default_LineRange = 8; public const int Default_LineRange = 8;
public const byte Default_OpcodeBase = 9; public const byte Default_OpcodeBase = 9;
public const bool SuppressDuplicates = true;
#endregion #endregion
public const byte DW_LNS_copy = 1; public const byte DW_LNS_copy = 1;
@ -822,7 +830,7 @@ namespace Mono.CompilerServices.SymbolWriter
this._line_numbers = lines; 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; int start = (int) bw.BaseStream.Position;
@ -832,11 +840,6 @@ namespace Mono.CompilerServices.SymbolWriter
int line_inc = LineNumbers [i].Row - last_line; int line_inc = LineNumbers [i].Row - last_line;
int offset_inc = LineNumbers [i].Offset - last_offset; 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) { if (LineNumbers [i].File != last_file) {
bw.Write (DW_LNS_set_file); bw.Write (DW_LNS_set_file);
bw.WriteLeb128 (LineNumbers [i].File); bw.WriteLeb128 (LineNumbers [i].File);
@ -884,17 +887,23 @@ namespace Mono.CompilerServices.SymbolWriter
bw.Write ((byte) 1); bw.Write ((byte) 1);
bw.Write (DW_LNE_end_sequence); 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; 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); LineNumberTable lnt = new LineNumberTable (file);
lnt.DoRead (file, br); lnt.DoRead (file, br, readColumnsInfo);
return lnt; return lnt;
} }
void DoRead (MonoSymbolFile file, MyBinaryReader br) void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns)
{ {
var lines = new List<LineNumberEntry> (); var lines = new List<LineNumberEntry> ();
@ -911,7 +920,7 @@ namespace Mono.CompilerServices.SymbolWriter
if (opcode == DW_LNE_end_sequence) { if (opcode == DW_LNE_end_sequence) {
if (modified) if (modified)
lines.Add (new LineNumberEntry ( lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden)); stm_file, stm_line, -1, stm_offset, is_hidden));
break; break;
} else if (opcode == DW_LNE_MONO_negate_is_hidden) { } else if (opcode == DW_LNE_MONO_negate_is_hidden) {
is_hidden = !is_hidden; is_hidden = !is_hidden;
@ -929,7 +938,7 @@ namespace Mono.CompilerServices.SymbolWriter
switch (opcode) { switch (opcode) {
case DW_LNS_copy: case DW_LNS_copy:
lines.Add (new LineNumberEntry ( lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden)); stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false; modified = false;
break; break;
case DW_LNS_advance_pc: case DW_LNS_advance_pc:
@ -959,13 +968,20 @@ namespace Mono.CompilerServices.SymbolWriter
stm_offset += opcode / LineRange; stm_offset += opcode / LineRange;
stm_line += LineBase + (opcode % LineRange); stm_line += LineBase + (opcode % LineRange);
lines.Add (new LineNumberEntry ( lines.Add (new LineNumberEntry (
stm_file, stm_line, stm_offset, is_hidden)); stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false; modified = false;
} }
} }
_line_numbers = new LineNumberEntry [lines.Count]; _line_numbers = lines.ToArray ();
lines.CopyTo (_line_numbers, 0);
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) public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end)
@ -1022,7 +1038,8 @@ namespace Mono.CompilerServices.SymbolWriter
[Flags] [Flags]
public enum Flags public enum Flags
{ {
LocalNamesAmbiguous = 1 LocalNamesAmbiguous = 1,
ColumnsInfoIncluded = 1 << 1
} }
public const int Size = 12; public const int Size = 12;
@ -1176,7 +1193,7 @@ namespace Mono.CompilerServices.SymbolWriter
} }
LineNumberTableOffset = (int) bw.BaseStream.Position; LineNumberTableOffset = (int) bw.BaseStream.Position;
lnt.Write (file, bw); lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0);
DataOffset = (int) bw.BaseStream.Position; DataOffset = (int) bw.BaseStream.Position;
@ -1204,7 +1221,7 @@ namespace Mono.CompilerServices.SymbolWriter
long old_pos = reader.BaseStream.Position; long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = LineNumberTableOffset; reader.BaseStream.Position = LineNumberTableOffset;
lnt = LineNumberTable.Read (SymbolFile, reader); lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0);
reader.BaseStream.Position = old_pos; reader.BaseStream.Position = old_pos;
return lnt; return lnt;

4
NRefactory/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) public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
{ {
int file_idx = file != null ? file.Index : 0; 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) { if (method_lines.Count > 0) {
var prev = method_lines[method_lines.Count - 1]; var prev = method_lines[method_lines.Count - 1];
@ -185,7 +185,7 @@ namespace Mono.CompilerServices.SymbolWriter
{ {
MethodEntry entry = new MethodEntry ( MethodEntry entry = new MethodEntry (
file, _comp_unit.Entry, token, ScopeVariables, 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); file.AddMethod (entry);
} }

80
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs

@ -315,7 +315,7 @@ namespace Mono.CSharp {
} }
var hoisted = localVariable.HoistedVariant; var hoisted = localVariable.HoistedVariant;
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) { if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) {
// TODO: It's too late the field is defined in HoistedLocalVariable ctor // TODO: It's too late the field is defined in HoistedLocalVariable ctor
hoisted.Storey.hoisted_locals.Remove (hoisted); hoisted.Storey.hoisted_locals.Remove (hoisted);
hoisted = null; hoisted = null;
@ -331,7 +331,7 @@ namespace Mono.CSharp {
hoisted_locals.Add (hoisted); hoisted_locals.Add (hoisted);
} }
if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit) if (ec.CurrentBlock.Explicit != localVariable.Block.Explicit && !(hoisted.Storey is StateMachine))
hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit); hoisted.Storey.AddReferenceFromChildrenBlock (ec.CurrentBlock.Explicit);
} }
@ -343,7 +343,7 @@ namespace Mono.CSharp {
var hoisted = parameterInfo.Parameter.HoistedVariant; var hoisted = parameterInfo.Parameter.HoistedVariant;
if (parameterInfo.Block.StateMachine is AsyncTaskStorey) { if (parameterInfo.Block.StateMachine != null) {
// //
// Another storey in same block exists but state machine does not // Another storey in same block exists but state machine does not
// have parameter captured. We need to add it there as well to // have parameter captured. We need to add it there as well to
@ -365,7 +365,7 @@ namespace Mono.CSharp {
// Lift captured parameter from value type storey to reference type one. Otherwise // Lift captured parameter from value type storey to reference type one. Otherwise
// any side effects would be done on a copy // any side effects would be done on a copy
// //
if (hoisted != null && hoisted.Storey != this && hoisted.Storey.Kind == MemberKind.Struct) { if (hoisted != null && hoisted.Storey != this && hoisted.Storey is StateMachine) {
if (hoisted_local_params == null) if (hoisted_local_params == null)
hoisted_local_params = new List<HoistedParameter> (); hoisted_local_params = new List<HoistedParameter> ();
@ -488,7 +488,7 @@ namespace Mono.CSharp {
// When the current context is async (or iterator) lift local storey // When the current context is async (or iterator) lift local storey
// instantiation to the currect storey // instantiation to the currect storey
// //
if (ec.CurrentAnonymousMethod is StateMachineInitializer) { if (ec.CurrentAnonymousMethod is StateMachineInitializer && (block.HasYield || block.HasAwait)) {
// //
// Unfortunately, normal capture mechanism could not be used because we are // Unfortunately, normal capture mechanism could not be used because we are
// too late in the pipeline and standart assign cannot be used either due to // too late in the pipeline and standart assign cannot be used either due to
@ -702,7 +702,7 @@ namespace Mono.CSharp {
public override void Emit (EmitContext ec) public override void Emit (EmitContext ec)
{ {
ResolveContext rc = new ResolveContext (ec.MemberContext); ResolveContext rc = new ResolveContext (ec.MemberContext);
Expression e = hv.GetFieldExpression (ec).CreateExpressionTree (rc); Expression e = hv.GetFieldExpression (ec).CreateExpressionTree (rc, false);
// This should never fail // This should never fail
e = e.Resolve (rc); e = e.Resolve (rc);
if (e != null) if (e != null)
@ -816,7 +816,7 @@ namespace Mono.CSharp {
sealed class HoistedFieldAssign : CompilerAssign sealed class HoistedFieldAssign : CompilerAssign
{ {
public HoistedFieldAssign (Expression target, Expression source) public HoistedFieldAssign (Expression target, Expression source)
: base (target, source, source.Location) : base (target, source, target.Location)
{ {
} }
@ -965,6 +965,11 @@ namespace Mono.CSharp {
get; get;
internal set; internal set;
} }
public ReportPrinter TypeInferenceReportPrinter {
get; set;
}
#endregion #endregion
// //
@ -975,7 +980,13 @@ namespace Mono.CSharp {
{ {
using (ec.With (ResolveContext.Options.InferReturnType, false)) { using (ec.With (ResolveContext.Options.InferReturnType, false)) {
using (ec.Set (ResolveContext.Options.ProbingMode)) { using (ec.Set (ResolveContext.Options.ProbingMode)) {
return Compatible (ec, delegate_type) != null; var prev = ec.Report.SetPrinter (TypeInferenceReportPrinter ?? new NullReportPrinter ());
var res = Compatible (ec, delegate_type) != null;
ec.Report.SetPrinter (prev);
return res;
} }
} }
} }
@ -1109,12 +1120,23 @@ namespace Mono.CSharp {
} }
using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) { using (ec.Set (ResolveContext.Options.ProbingMode | ResolveContext.Options.InferReturnType)) {
ReportPrinter prev;
if (TypeInferenceReportPrinter != null) {
prev = ec.Report.SetPrinter (TypeInferenceReportPrinter);
} else {
prev = null;
}
var body = CompatibleMethodBody (ec, tic, null, delegate_type); var body = CompatibleMethodBody (ec, tic, null, delegate_type);
if (body != null) { if (body != null) {
am = body.Compatible (ec, body); am = body.Compatible (ec, body);
} else { } else {
am = null; am = null;
} }
if (TypeInferenceReportPrinter != null) {
ec.Report.SetPrinter (prev);
}
} }
if (am == null) if (am == null)
@ -1476,8 +1498,15 @@ namespace Mono.CSharp {
if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion))
flags |= ResolveContext.Options.ExpressionTreeConversion; flags |= ResolveContext.Options.ExpressionTreeConversion;
if (ec.HasSet (ResolveContext.Options.BaseInitializer))
flags |= ResolveContext.Options.BaseInitializer;
aec.Set (flags); aec.Set (flags);
var bc = ec as BlockContext;
if (bc != null)
aec.FlowOffset = bc.FlowOffset;
var errors = ec.Report.Errors; var errors = ec.Report.Errors;
bool res = Block.Resolve (ec.CurrentBranching, aec, null); bool res = Block.Resolve (ec.CurrentBranching, aec, null);
@ -1988,11 +2017,11 @@ namespace Mono.CSharp {
IntConstant FNV_prime = new IntConstant (Compiler.BuiltinTypes, 16777619, loc); IntConstant FNV_prime = new IntConstant (Compiler.BuiltinTypes, 16777619, loc);
rs_hashcode = new Binary (Binary.Operator.Multiply, rs_hashcode = new Binary (Binary.Operator.Multiply,
new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode, loc), new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode),
FNV_prime, loc); FNV_prime);
Expression field_to_string = new Conditional (new BooleanExpression (new Binary (Binary.Operator.Inequality, 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 Invocation (new MemberAccess (
new MemberAccess (new This (f.Location), f.Name), "ToString"), null), new MemberAccess (new This (f.Location), f.Name), "ToString"), null),
new StringConstant (Compiler.BuiltinTypes, string.Empty, loc), loc); new StringConstant (Compiler.BuiltinTypes, string.Empty, loc), loc);
@ -2003,9 +2032,7 @@ namespace Mono.CSharp {
string_concat, string_concat,
new Binary (Binary.Operator.Addition, new Binary (Binary.Operator.Addition,
new StringConstant (Compiler.BuiltinTypes, " " + p.Name + " = ", loc), new StringConstant (Compiler.BuiltinTypes, " " + p.Name + " = ", loc),
field_to_string, field_to_string));
loc),
loc);
continue; continue;
} }
@ -2015,18 +2042,15 @@ namespace Mono.CSharp {
string_concat = new Binary (Binary.Operator.Addition, string_concat = new Binary (Binary.Operator.Addition,
new Binary (Binary.Operator.Addition, new Binary (Binary.Operator.Addition,
string_concat, string_concat,
new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc), new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc)),
loc), field_to_string);
field_to_string,
loc);
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 Binary (Binary.Operator.Addition,
string_concat, string_concat,
new StringConstant (Compiler.BuiltinTypes, " }", loc), new StringConstant (Compiler.BuiltinTypes, " }", loc));
loc);
// //
// Equals (object obj) override // Equals (object obj) override
@ -2037,9 +2061,9 @@ namespace Mono.CSharp {
new As (equals_block.GetParameterReference (0, loc), new As (equals_block.GetParameterReference (0, loc),
current_type, loc), 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) 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.AddStatement (new Return (equals_test, loc));
equals.Block = equals_block; equals.Block = equals_block;
@ -2081,19 +2105,19 @@ namespace Mono.CSharp {
var hash_variable = new LocalVariableReference (li_hash, loc); var hash_variable = new LocalVariableReference (li_hash, loc);
hashcode_block.AddStatement (new StatementExpression ( hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable, 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 ( hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable, 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 ( hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable, 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 ( hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable, 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 ( hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable, 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.AddStatement (new Return (hash_variable, loc));
hashcode.Block = hashcode_top; hashcode.Block = hashcode_top;

16
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs

@ -320,20 +320,20 @@ namespace Mono.CSharp
if (a.Expr is Constant) { if (a.Expr is Constant) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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) { } else if (a.ArgType == Argument.AType.Ref) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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, 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) { } else if (a.ArgType == Argument.AType.Out) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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, 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) { } else if (a.ArgType == Argument.AType.DynamicTypeName) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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; var arg_type = a.Expr.Type;
@ -354,14 +354,14 @@ namespace Mono.CSharp
} }
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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; string named_value;
NamedArgument na = a as NamedArgument; NamedArgument na = a as NamedArgument;
if (na != null) { if (na != null) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, 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; named_value = na.Name;
} else { } else {

7
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assembly.cs

@ -624,10 +624,17 @@ namespace Mono.CSharp
new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"), new MemberAccess (system_security_permissions, "SecurityPermissionAttribute"),
new Arguments[] { pos, named }, loc, false); new Arguments[] { pos, named }, loc, false);
g.AttachTo (module, module); g.AttachTo (module, module);
// Disable no-location warnings (e.g. obsolete) for compiler generated attribute
Compiler.Report.DisableReporting ();
try {
var ctor = g.Resolve (); var ctor = g.Resolve ();
if (ctor != null) { if (ctor != null) {
g.ExtractSecurityPermissionSet (ctor, ref declarative_security); g.ExtractSecurityPermissionSet (ctor, ref declarative_security);
} }
} finally {
Compiler.Report.EnableReporting ();
}
} }
if (module.OptAttributes == null) if (module.OptAttributes == null)

16
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs

@ -543,11 +543,11 @@ namespace Mono.CSharp {
ExpressionStatement resolved; ExpressionStatement resolved;
IMemberContext mc; IMemberContext mc;
public FieldInitializer (FieldSpec spec, Expression expression, IMemberContext mc) public FieldInitializer (FieldBase mc, Expression expression, Location loc)
: base (new FieldExpr (spec, expression.Location), expression, expression.Location) : base (new FieldExpr (mc.Spec, expression.Location), expression, loc)
{ {
this.mc = mc; this.mc = mc;
if (!spec.IsStatic) if (!mc.IsStatic)
((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location); ((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) public CompoundAssign (Binary.Operator op, Expression target, Expression source)
: base (target, source, loc) : base (target, source, target.Location)
{ {
right = source; right = source;
this.op = op; this.op = op;
} }
public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left, Location loc) public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left)
: this (op, target, source, loc) : this (op, target, source)
{ {
this.left = left; this.left = left;
} }
@ -731,7 +731,7 @@ namespace Mono.CSharp {
if (left == null) if (left == null)
left = new TargetExpression (target); left = new TargetExpression (target);
source = new Binary (op, left, right, true, loc); source = new Binary (op, left, right, true);
if (target is DynamicMemberAssignable) { if (target is DynamicMemberAssignable) {
Arguments targs = ((DynamicMemberAssignable) target).Arguments; Arguments targs = ((DynamicMemberAssignable) target).Arguments;

10
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs

@ -227,7 +227,9 @@ namespace Mono.CSharp
// //
// awaiter = expr.GetAwaiter (); // awaiter = expr.GetAwaiter ();
// //
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
fe_awaiter.EmitAssign (ec, expr, false, false); fe_awaiter.EmitAssign (ec, expr, false, false);
}
Label skip_continuation = ec.DefineLabel (); Label skip_continuation = ec.DefineLabel ();
@ -284,15 +286,9 @@ namespace Mono.CSharp
awaiter.IsAvailableForReuse = true; awaiter.IsAvailableForReuse = true;
if (ResultType.Kind != MemberKind.Void) { if (ResultType.Kind != MemberKind.Void)
var storey = (AsyncTaskStorey) machine_initializer.Storey;
if (storey.HoistedReturn != null)
storey.HoistedReturn.EmitAssign (ec);
else
ec.Emit (OpCodes.Pop); ec.Emit (OpCodes.Pop);
} }
}
void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter) void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
{ {

45
NRefactory/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) { if (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
var value = ((Constant) pos_args[0].Expr).GetValue () as string; var value = ((Constant) pos_args[0].Expr).GetValue () as string;
if (string.IsNullOrEmpty (value)) 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 && } else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
!System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) { !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); 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 // Encodes single property named argument per call
// //
@ -1629,6 +1635,10 @@ namespace Mono.CSharp {
// New in .NET 4.0 // New in .NET 4.0
public readonly PredefinedDynamicAttribute Dynamic; 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 // 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"); StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute"); 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"); CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute"); CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute"); 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 public class PredefinedDynamicAttribute : PredefinedAttribute
{ {
MethodSpec tctor; MethodSpec tctor;

40
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs

@ -187,7 +187,7 @@ namespace Mono.CSharp {
// //
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) || if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left 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 // false | null => null
// null | false => null // null | false => null
@ -231,7 +231,7 @@ namespace Mono.CSharp {
// //
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) || if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left 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 // false & null => false
// null & false => false // null & false => false
@ -469,7 +469,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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)) if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -566,7 +566,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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)) if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -662,7 +662,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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)) if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -762,7 +762,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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)) if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@ -852,7 +852,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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; IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@ -873,7 +873,7 @@ namespace Mono.CSharp {
// null << value => null // null << value => null
if (left is NullLiteral) 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); left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@ -889,7 +889,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) { if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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; IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@ -909,7 +909,7 @@ namespace Mono.CSharp {
// null >> value => null // null >> value => null
if (left is NullLiteral) 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); left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int) if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@ -925,7 +925,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) { if (left.IsNull || right.IsNull) {
return ReducedExpression.Create ( return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull == right.IsNull, left.Location), 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) if (left is StringConstant && right is StringConstant)
@ -969,7 +969,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) { if (left.IsNull || right.IsNull) {
return ReducedExpression.Create ( return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull != right.IsNull, left.Location), 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) if (left is StringConstant && right is StringConstant)
@ -1011,11 +1011,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) { if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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) { 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) { if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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) { 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) { if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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) { 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) { if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc); var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec); 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) { 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);
} }
} }

52
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs

@ -70,6 +70,12 @@ namespace Mono.CSharp
} }
} }
public Dictionary<string, MemberCore> DefinedNames {
get {
return defined_names;
}
}
public TypeDefinition PartialContainer { public TypeDefinition PartialContainer {
get { get {
return main_container; return main_container;
@ -340,12 +346,31 @@ namespace Mono.CSharp
return MemberName.GetSignatureForError (); 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) public virtual void RemoveContainer (TypeContainer cont)
{ {
if (containers != null) if (containers != null)
containers.Remove (cont); containers.Remove (cont);
defined_names.Remove (cont.Basename); var tc = Parent == Module ? Module : this;
tc.defined_names.Remove (cont.Basename);
} }
public virtual void VerifyMembers () public virtual void VerifyMembers ()
@ -1838,13 +1863,20 @@ namespace Mono.CSharp
return; return;
string class_indexer_name = null; string class_indexer_name = null;
has_normal_indexers = true;
// //
// Check normal indexers for consistent name, explicit interface implementation // Check normal indexers for consistent name, explicit interface implementation
// indexers are ignored // indexers are ignored
// //
foreach (var indexer in indexers) { 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) { if (class_indexer_name == null) {
indexer_name = class_indexer_name = indexer.Name; indexer_name = class_indexer_name = indexer.Name;
continue; continue;
@ -1922,7 +1954,7 @@ namespace Mono.CSharp
continue; continue;
// //
// Don't be pendatic over serializable attributes // Don't be pedantic when type requires specific layout
// //
if (f.OptAttributes != null || PartialContainer.HasStructLayout) if (f.OptAttributes != null || PartialContainer.HasStructLayout)
continue; continue;
@ -1934,10 +1966,6 @@ namespace Mono.CSharp
} else if (TypeSpec.IsReferenceType (f.MemberType)) { } else if (TypeSpec.IsReferenceType (f.MemberType)) {
value = "null"; value = "null";
} else { } else {
// Ignore this warning for struct value fields (they are always initialized)
if (f.MemberType.IsStruct)
continue;
value = null; value = null;
} }
@ -2403,16 +2431,6 @@ namespace Mono.CSharp
base.AddNameToContainer (symbol, name); base.AddNameToContainer (symbol, name);
} }
public override void VerifyMembers ()
{
base.VerifyMembers ();
if (containers != null) {
foreach (var t in containers)
t.VerifyMembers ();
}
}
public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa) public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
{ {
if (a.IsValidSecurityAttribute ()) { if (a.IsValidSecurityAttribute ()) {

16
NRefactory/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)) if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext, loc))
return; 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; Expression instance_copy = null;
@ -1006,6 +1006,18 @@ namespace Mono.CSharp
ec.Emit (OpCodes.Constrained, InstanceExpression.Type); 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 // Set instance expression to actual result expression. When it contains await it can be
// picked up by caller // picked up by caller

2
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs

@ -59,7 +59,7 @@ namespace Mono.CSharp {
if ((field_attr & FieldAttributes.InitOnly) != 0) if ((field_attr & FieldAttributes.InitOnly) != 0)
Parent.PartialContainer.RegisterFieldForInitialization (this, Parent.PartialContainer.RegisterFieldForInitialization (this,
new FieldInitializer (spec, initializer, this)); new FieldInitializer (this, initializer, Location));
if (declarators != null) { if (declarators != null) {
var t = new TypeExpression (MemberType, TypeExpression.Location); var t = new TypeExpression (MemberType, TypeExpression.Location);

25
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs

@ -13,6 +13,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Security.Cryptography;
namespace Mono.CSharp namespace Mono.CSharp
{ {
@ -730,4 +731,28 @@ namespace Mono.CSharp
return new FlagsHandle (this, options, enable ? options : 0); 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<char[], string>[] Identifiers = new Dictionary<char[], string>[Tokenizer.MaxIdentifierLength + 1];
public readonly List<Parameter> ParametersStack = new List<Parameter> (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 ());
}
}
} }

3
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/convert.cs

@ -1337,8 +1337,7 @@ namespace Mono.CSharp {
try { try {
c = c.ConvertImplicitly (target_type); c = c.ConvertImplicitly (target_type);
} catch { } catch {
Console.WriteLine ("Conversion error happened in line {0}", loc); throw new InternalErrorException ("Conversion error", loc);
throw;
} }
if (c != null) if (c != null)
return c; return c;

9492
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs

File diff suppressed because it is too large Load Diff

230
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.jay

@ -10,12 +10,7 @@
// //
// (C) 2001 Ximian, Inc (http://www.ximian.com) // (C) 2001 Ximian, Inc (http://www.ximian.com)
// (C) 2004-2011 Novell, Inc // (C) 2004-2011 Novell, Inc
// Copyright 2011 Xamarin Inc. // Copyright 2011-2012 Xamarin Inc.
//
// TODO:
// (1) Figure out why error productions dont work. `type-declaration' is a
// great spot to put an `error' because you can reproduce it with this input:
// "public X { }"
// //
using System.Text; using System.Text;
@ -81,7 +76,7 @@ namespace Mono.CSharp
/// ///
/// An out-of-band stack. /// An out-of-band stack.
/// ///
static Stack<object> oob_stack; Stack<object> oob_stack;
/// ///
/// Controls the verbosity of the errors produced by the parser /// Controls the verbosity of the errors produced by the parser
@ -137,7 +132,7 @@ namespace Mono.CSharp
// share the bucket for very common constructs which can never // share the bucket for very common constructs which can never
// be recursive // be recursive
// //
static List<Parameter> parameters_bucket = new List<Parameter> (6); List<Parameter> parameters_bucket;
// //
// Full AST support members // Full AST support members
@ -2669,6 +2664,22 @@ enum_member_declaration
$$ = em; $$ = em;
} }
| opt_attributes IDENTIFIER error
{
Error_SyntaxError (yyToken);
var lt = (Tokenizer.LocatedToken) $2;
var em = new EnumMember ((Enum) current_type, new MemberName (lt.Value, lt.Location), (Attributes) $1);
((Enum) current_type).AddEnumMember (em);
if (doc_support) {
em.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
$$ = em;
}
| attributes_without_members
; ;
delegate_declaration delegate_declaration
@ -3196,6 +3207,14 @@ invocation_expression
$$ = new Invocation ((Expression) $1, (Arguments) $3); $$ = new Invocation ((Expression) $1, (Arguments) $3);
lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4)); lbag.AddLocation ($$, GetLocation ($2), GetLocation ($4));
} }
| primary_expression open_parens_any argument_list error
{
Error_SyntaxError (yyToken);
$$ = new Invocation ((Expression) $1, (Arguments) $3);
lbag.AddLocation ($$, GetLocation ($2));
}
; ;
opt_object_or_collection_initializer opt_object_or_collection_initializer
@ -3207,8 +3226,8 @@ object_or_collection_initializer
: OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion : OPEN_BRACE opt_member_initializer_list close_brace_or_complete_completion
{ {
if ($2 == null) { if ($2 == null) {
$$ = CollectionOrObjectInitializers.Empty; $$ = new CollectionOrObjectInitializers (new List<Expression> (), GetLocation ($1));
// TODO: lbag lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
} else { } else {
$$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1)); $$ = new CollectionOrObjectInitializers ((List<Expression>) $2, GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3)); lbag.AddLocation ($$, GetLocation ($1), GetLocation ($3));
@ -3279,7 +3298,8 @@ member_initializer
| OPEN_BRACE CLOSE_BRACE | OPEN_BRACE CLOSE_BRACE
{ {
report.Error (1920, GetLocation ($1), "An element initializer cannot be empty"); report.Error (1920, GetLocation ($1), "An element initializer cannot be empty");
$$ = null; $$ = new CollectionElementInitializer (new List<Expression> (), GetLocation ($1));
lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -3327,6 +3347,7 @@ argument_list
} }
| argument_list COMMA error | argument_list COMMA error
{ {
lexer.putback (')'); // TODO: Wrong but what can I do
Error_SyntaxError (yyToken); Error_SyntaxError (yyToken);
$$ = $1; $$ = $1;
} }
@ -3955,18 +3976,18 @@ multiplicative_expression
: prefixed_unary_expression : prefixed_unary_expression
| multiplicative_expression STAR prefixed_unary_expression | multiplicative_expression STAR prefixed_unary_expression
{ {
$$ = new Binary (Binary.Operator.Multiply, $$ = new Binary (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| multiplicative_expression DIV prefixed_unary_expression | multiplicative_expression DIV prefixed_unary_expression
{ {
$$ = new Binary (Binary.Operator.Division, $$ = new Binary (Binary.Operator.Division, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| multiplicative_expression PERCENT prefixed_unary_expression | multiplicative_expression PERCENT prefixed_unary_expression
{ {
$$ = new Binary (Binary.Operator.Modulus, $$ = new Binary (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -3974,17 +3995,13 @@ additive_expression
: multiplicative_expression : multiplicative_expression
| additive_expression PLUS multiplicative_expression | additive_expression PLUS multiplicative_expression
{ {
$$ = new Binary (Binary.Operator.Addition, $$ = new Binary (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| additive_expression MINUS multiplicative_expression | additive_expression MINUS multiplicative_expression
{ {
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2)); $$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
} lbag.AddLocation ($$, GetLocation ($2));
| parenthesized_expression MINUS multiplicative_expression
{
// Shift/Reduce conflict
$$ = new Binary (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2));
} }
| additive_expression AS type | additive_expression AS type
{ {
@ -4000,13 +4017,13 @@ shift_expression
: additive_expression : additive_expression
| shift_expression OP_SHIFT_LEFT additive_expression | shift_expression OP_SHIFT_LEFT additive_expression
{ {
$$ = new Binary (Binary.Operator.LeftShift, $$ = new Binary (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| shift_expression OP_SHIFT_RIGHT additive_expression | shift_expression OP_SHIFT_RIGHT additive_expression
{ {
$$ = new Binary (Binary.Operator.RightShift, $$ = new Binary (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4014,23 +4031,23 @@ relational_expression
: shift_expression : shift_expression
| relational_expression OP_LT shift_expression | relational_expression OP_LT shift_expression
{ {
$$ = new Binary (Binary.Operator.LessThan, $$ = new Binary (Binary.Operator.LessThan, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| relational_expression OP_GT shift_expression | relational_expression OP_GT shift_expression
{ {
$$ = new Binary (Binary.Operator.GreaterThan, $$ = new Binary (Binary.Operator.GreaterThan, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| relational_expression OP_LE shift_expression | relational_expression OP_LE shift_expression
{ {
$$ = new Binary (Binary.Operator.LessThanOrEqual, $$ = new Binary (Binary.Operator.LessThanOrEqual, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| relational_expression OP_GE shift_expression | relational_expression OP_GE shift_expression
{ {
$$ = new Binary (Binary.Operator.GreaterThanOrEqual, $$ = new Binary (Binary.Operator.GreaterThanOrEqual, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4038,13 +4055,13 @@ equality_expression
: relational_expression : relational_expression
| equality_expression OP_EQ relational_expression | equality_expression OP_EQ relational_expression
{ {
$$ = new Binary (Binary.Operator.Equality, $$ = new Binary (Binary.Operator.Equality, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| equality_expression OP_NE relational_expression | equality_expression OP_NE relational_expression
{ {
$$ = new Binary (Binary.Operator.Inequality, $$ = new Binary (Binary.Operator.Inequality, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4052,8 +4069,8 @@ and_expression
: equality_expression : equality_expression
| and_expression BITWISE_AND equality_expression | and_expression BITWISE_AND equality_expression
{ {
$$ = new Binary (Binary.Operator.BitwiseAnd, $$ = new Binary (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4061,8 +4078,8 @@ exclusive_or_expression
: and_expression : and_expression
| exclusive_or_expression CARRET and_expression | exclusive_or_expression CARRET and_expression
{ {
$$ = new Binary (Binary.Operator.ExclusiveOr, $$ = new Binary (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4070,8 +4087,8 @@ inclusive_or_expression
: exclusive_or_expression : exclusive_or_expression
| inclusive_or_expression BITWISE_OR exclusive_or_expression | inclusive_or_expression BITWISE_OR exclusive_or_expression
{ {
$$ = new Binary (Binary.Operator.BitwiseOr, $$ = new Binary (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4079,8 +4096,8 @@ conditional_and_expression
: inclusive_or_expression : inclusive_or_expression
| conditional_and_expression OP_AND inclusive_or_expression | conditional_and_expression OP_AND inclusive_or_expression
{ {
$$ = new Binary (Binary.Operator.LogicalAnd, $$ = new Binary (Binary.Operator.LogicalAnd, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4088,8 +4105,8 @@ conditional_or_expression
: conditional_and_expression : conditional_and_expression
| conditional_or_expression OP_OR conditional_and_expression | conditional_or_expression OP_OR conditional_and_expression
{ {
$$ = new Binary (Binary.Operator.LogicalOr, $$ = new Binary (Binary.Operator.LogicalOr, (Expression) $1, (Expression) $3);
(Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4100,7 +4117,8 @@ null_coalescing_expression
if (lang_version < LanguageVersion.ISO_2) if (lang_version < LanguageVersion.ISO_2)
FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator"); FeatureIsNotAvailable (GetLocation ($2), "null coalescing operator");
$$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3, GetLocation ($2)); $$ = new Nullable.NullCoalescingOperator ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4121,57 +4139,58 @@ conditional_expression
assignment_expression assignment_expression
: prefixed_unary_expression ASSIGN expression : prefixed_unary_expression ASSIGN expression
{ {
$$ = new SimpleAssign ((Expression) $1, (Expression) $3, GetLocation ($2)); $$ = new SimpleAssign ((Expression) $1, (Expression) $3);
lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_MULT_ASSIGN expression | prefixed_unary_expression OP_MULT_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.Multiply, (Expression) $1, (Expression) $3);
Binary.Operator.Multiply, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_DIV_ASSIGN expression | prefixed_unary_expression OP_DIV_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.Division, (Expression) $1, (Expression) $3);
Binary.Operator.Division, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_MOD_ASSIGN expression | prefixed_unary_expression OP_MOD_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.Modulus, (Expression) $1, (Expression) $3);
Binary.Operator.Modulus, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_ADD_ASSIGN expression | prefixed_unary_expression OP_ADD_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.Addition, (Expression) $1, (Expression) $3);
Binary.Operator.Addition, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_SUB_ASSIGN expression | prefixed_unary_expression OP_SUB_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.Subtraction, (Expression) $1, (Expression) $3);
Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression | prefixed_unary_expression OP_SHIFT_LEFT_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.LeftShift, (Expression) $1, (Expression) $3);
Binary.Operator.LeftShift, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression | prefixed_unary_expression OP_SHIFT_RIGHT_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.RightShift, (Expression) $1, (Expression) $3);
Binary.Operator.RightShift, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_AND_ASSIGN expression | prefixed_unary_expression OP_AND_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3);
Binary.Operator.BitwiseAnd, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_OR_ASSIGN expression | prefixed_unary_expression OP_OR_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3);
Binary.Operator.BitwiseOr, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
| prefixed_unary_expression OP_XOR_ASSIGN expression | prefixed_unary_expression OP_XOR_ASSIGN expression
{ {
$$ = new CompoundAssign ( $$ = new CompoundAssign (Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3);
Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $3, GetLocation ($2)); lbag.AddLocation ($$, GetLocation ($2));
} }
; ;
@ -4965,7 +4984,7 @@ identifier_inside_body
{ {
if (async_block) { if (async_block) {
report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression"); report.Error (4003, GetLocation ($1), "`await' cannot be used as an identifier within an async method or lambda expression");
$$ = Tokenizer.LocatedToken.Create ("await", GetLocation ($1)); $$ = new Tokenizer.LocatedToken ("await", GetLocation ($1));
} }
} }
; ;
@ -5347,19 +5366,19 @@ while_statement
do_statement do_statement
: DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON : DO embedded_statement WHILE open_parens_any boolean_expression CLOSE_PARENS SEMICOLON
{ {
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1)); $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7)); lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4), GetLocation ($6), GetLocation ($7));
} }
| DO embedded_statement error | DO embedded_statement error
{ {
Error_SyntaxError (yyToken); Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, null, GetLocation ($1)); $$ = new Do ((Statement) $2, null, GetLocation ($1), Location.Null);
} }
| DO embedded_statement WHILE open_parens_any boolean_expression error | DO embedded_statement WHILE open_parens_any boolean_expression error
{ {
Error_SyntaxError (yyToken); Error_SyntaxError (yyToken);
$$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1)); $$ = new Do ((Statement) $2, (BooleanExpression) $5, GetLocation ($1), GetLocation ($3));
lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4)); lbag.AddStatement ($$, GetLocation ($3), GetLocation ($4));
} }
; ;
@ -5414,6 +5433,7 @@ for_statement_condition
{ {
$$ = $4; $$ = $4;
} }
| boolean_expression CLOSE_PARENS { | boolean_expression CLOSE_PARENS {
report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'"); report.Error (1525, GetLocation ($2), "Unexpected symbol ')', expected ';'");
For f = (For) $0; For f = (For) $0;
@ -5627,6 +5647,11 @@ return_statement
$$ = new Return ((Expression) $2, GetLocation ($1)); $$ = new Return ((Expression) $2, GetLocation ($1));
lbag.AddStatement ($$, GetLocation ($3)); lbag.AddStatement ($$, GetLocation ($3));
} }
| RETURN expression error
{
Error_SyntaxError (yyToken);
$$ = new Return ((Expression) $2, GetLocation ($1));
}
| RETURN error | RETURN error
{ {
Error_SyntaxError (yyToken); Error_SyntaxError (yyToken);
@ -5664,6 +5689,24 @@ yield_statement
$$ = new Yield ((Expression) $3, lt.Location); $$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4)); lbag.AddStatement ($$, GetLocation ($2), GetLocation ($4));
} }
| identifier_inside_body RETURN expression error
{
Error_SyntaxError (yyToken);
var lt = (Tokenizer.LocatedToken) $1;
string s = lt.Value;
if (s != "yield"){
report.Error (1003, lt.Location, "; expected");
} else if ($3 == null) {
report.Error (1627, GetLocation ($4), "Expression expected after yield return");
} else if (lang_version == LanguageVersion.ISO_1){
FeatureIsNotAvailable (lt.Location, "iterators");
}
current_block.Explicit.RegisterIteratorYield ();
$$ = new Yield ((Expression) $3, lt.Location);
lbag.AddStatement ($$, GetLocation ($2));
}
| identifier_inside_body BREAK SEMICOLON | identifier_inside_body BREAK SEMICOLON
{ {
var lt = (Tokenizer.LocatedToken) $1; var lt = (Tokenizer.LocatedToken) $1;
@ -6762,17 +6805,12 @@ public Tokenizer Lexer {
} }
} }
static CSharpParser () public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, ParserSession session)
{ : this (reader, file, file.Compiler.Report, session)
oob_stack = new Stack<object> ();
}
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file)
: this (reader, file, file.Compiler.Report)
{ {
} }
public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report) public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Report report, ParserSession session)
{ {
this.file = file; this.file = file;
current_container = current_namespace = file; current_container = current_namespace = file;
@ -6785,22 +6823,16 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re
lang_version = settings.Version; lang_version = settings.Version;
yacc_verbose_flag = settings.VerboseParserFlag; yacc_verbose_flag = settings.VerboseParserFlag;
doc_support = settings.DocumentationFile != null; doc_support = settings.DocumentationFile != null;
oob_stack.Clear (); lexer = new Tokenizer (reader, file, session);
lexer = new Tokenizer (reader, file); oob_stack = new Stack<object> ();
lbag = session.LocationsBag;
#if FULL_AST use_global_stacks = session.UseJayGlobalArrays;
lbag = new LocationsBag (); parameters_bucket = session.ParametersStack;
#else
lbag = null;
#endif
use_global_stacks = true;
} }
public void parse () public void parse ()
{ {
eof_token = Token.EOF; eof_token = Token.EOF;
Tokenizer.LocatedToken.Initialize ();
try { try {
if (yacc_verbose_flag > 1) if (yacc_verbose_flag > 1)
@ -6867,12 +6899,6 @@ Location GetLocation (object obj)
return lexer.Location; return lexer.Location;
} }
public LocationsBag LocationsBag {
get {
return lbag;
}
}
void start_block (Location loc) void start_block (Location loc)
{ {
if (current_block == null) { if (current_block == null) {

266
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs

@ -16,6 +16,7 @@ using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Diagnostics; using System.Diagnostics;
using System.Collections;
namespace Mono.CSharp namespace Mono.CSharp
{ {
@ -66,32 +67,62 @@ namespace Mono.CSharp
} }
// //
// This class has to be used in the parser only, it reuses token // This class has to be used by parser only, it reuses token
// details after each parse // details after each file parse completion
// //
public class LocatedToken public class LocatedToken
{ {
int row, column; public int row, column;
string value; public string value;
public SourceFile file;
static LocatedToken[] buffer = new LocatedToken[0]; public LocatedToken ()
static int pos; {
}
private LocatedToken () public LocatedToken (string value, Location loc)
{ {
this.value = value;
file = loc.SourceFile;
row = loc.Row;
column = loc.Column;
} }
public static LocatedToken Create (int row, int column) public override string ToString ()
{ {
return Create (null, row, column); return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
}
public Location Location {
get { return new Location (file, row, column); }
}
public string Value {
get { return value; }
}
} }
public static LocatedToken Create (string value, Location loc) public class LocatedTokenBuffer
{ {
return Create (value, loc.Row, loc.Column); readonly LocatedToken[] buffer;
public int pos;
public LocatedTokenBuffer ()
{
buffer = new LocatedToken[0];
}
public LocatedTokenBuffer (LocatedToken[] buffer)
{
this.buffer = buffer ?? new LocatedToken[0];
} }
public static LocatedToken Create (string value, int row, int column) public LocatedToken Create (SourceFile file, int row, int column)
{
return Create (null, file, row, column);
}
public LocatedToken Create (string value, SourceFile file, int row, int column)
{ {
// //
// TODO: I am not very happy about the logic but it's the best // TODO: I am not very happy about the logic but it's the best
@ -114,6 +145,7 @@ namespace Mono.CSharp
++pos; ++pos;
} }
entry.value = value; entry.value = value;
entry.file = file;
entry.row = row; entry.row = row;
entry.column = column; entry.column = column;
return entry; return entry;
@ -123,31 +155,9 @@ namespace Mono.CSharp
// Used for token not required by expression evaluator // Used for token not required by expression evaluator
// //
[Conditional ("FULL_AST")] [Conditional ("FULL_AST")]
public static void CreateOptional (int row, int col, ref object token) public void CreateOptional (SourceFile file, int row, int col, ref object token)
{ {
token = Create (row, col); token = Create (file, row, col);
}
public static void Initialize ()
{
#if !FULL_AST
if (buffer.Length == 0)
buffer = new LocatedToken [15000];
#endif
pos = 0;
}
public override string ToString ()
{
return string.Format ("Token '{0}' at {1},{2}", Value, row, column);
}
public Location Location {
get { return new Location (row, column); }
}
public string Value {
get { return value; }
} }
} }
@ -174,6 +184,7 @@ namespace Mono.CSharp
readonly SeekableStreamReader reader; readonly SeekableStreamReader reader;
readonly CompilationSourceFile source_file; readonly CompilationSourceFile source_file;
public CompilationSourceFile SourceFile { get { return source_file; } }
readonly CompilerContext context; readonly CompilerContext context;
SourceFile current_source; SourceFile current_source;
@ -192,6 +203,7 @@ namespace Mono.CSharp
List<Location> escaped_identifiers; List<Location> escaped_identifiers;
int parsing_generic_less_than; int parsing_generic_less_than;
readonly bool doc_processing; readonly bool doc_processing;
readonly LocatedTokenBuffer ltb;
// //
// Used mainly for parser optimizations. Some expressions for instance // Used mainly for parser optimizations. Some expressions for instance
@ -355,27 +367,15 @@ namespace Mono.CSharp
// //
Stack<int> ifstack; Stack<int> ifstack;
const int max_id_size = 512; public const int MaxIdentifierLength = 512;
const int max_number_size = 512; public const int MaxNumberLength = 512;
#if FULL_AST
readonly char [] id_builder = new char [max_id_size];
Dictionary<char[], string>[] identifiers = new Dictionary<char[], string>[max_id_size + 1];
char [] number_builder = new char [max_number_size]; readonly char[] id_builder;
readonly Dictionary<char[], string>[] identifiers;
readonly char[] number_builder;
int number_pos; int number_pos;
char[] value_builder = new char[256]; char[] value_builder = new char[64];
#else
static readonly char [] id_builder = new char [max_id_size];
static Dictionary<char[], string>[] identifiers = new Dictionary<char[], string>[max_id_size + 1];
static char [] number_builder = new char [max_number_size];
static int number_pos;
static char[] value_builder = new char[256];
#endif
public int Line { public int Line {
get { get {
@ -386,6 +386,15 @@ namespace Mono.CSharp
} }
} }
public int Column {
get {
return col;
}
set {
col = value;
}
}
// //
// This is used when the tokenizer needs to save // This is used when the tokenizer needs to save
// the current position as it needs to do some parsing // the current position as it needs to do some parsing
@ -430,11 +439,15 @@ namespace Mono.CSharp
} }
} }
public Tokenizer (SeekableStreamReader input, CompilationSourceFile file) public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session)
{ {
this.source_file = file; this.source_file = file;
this.context = file.Compiler; this.context = file.Compiler;
this.current_source = file.SourceFile; this.current_source = file.SourceFile;
this.identifiers = session.Identifiers;
this.id_builder = session.IDBuilder;
this.number_builder = session.NumberBuilder;
this.ltb = new LocatedTokenBuffer (session.LocatedTokens);
reader = input; reader = input;
@ -444,8 +457,6 @@ namespace Mono.CSharp
doc_processing = context.Settings.DocumentationFile != null; doc_processing = context.Settings.DocumentationFile != null;
tab_size = context.Settings.TabSize; tab_size = context.Settings.TabSize;
Mono.CSharp.Location.Push (current_source);
} }
public void PushPosition () public void PushPosition ()
@ -829,11 +840,13 @@ namespace Mono.CSharp
PushPosition (); PushPosition ();
xtoken (); xtoken ();
if (xtoken () != Token.ARROW) if (xtoken () != Token.ARROW)
res = -1; goto default;
PopPosition (); PopPosition ();
break; break;
default: default:
// peek_token could overwrite id_buffer
id_builder [0] = 'a'; id_builder [1] = 's'; id_builder [2] = 'y'; id_builder [3] = 'n'; id_builder [4] = 'c';
res = -1; res = -1;
break; break;
} }
@ -891,7 +904,7 @@ namespace Mono.CSharp
public Location Location { public Location Location {
get { get {
return new Location (ref_line, col); return new Location (current_source, ref_line, col);
} }
} }
@ -1104,9 +1117,14 @@ namespace Mono.CSharp
start: start:
int the_token = token (); int the_token = token ();
if (the_token == Token.OPEN_BRACKET) { if (the_token == Token.OPEN_BRACKET) {
do { while (true) {
the_token = token (); the_token = token ();
} while (the_token != Token.CLOSE_BRACKET); if (the_token == Token.EOF)
return true;
if (the_token == Token.CLOSE_BRACKET)
break;
}
the_token = token (); the_token = token ();
} else if (the_token == Token.IN || the_token == Token.OUT) { } else if (the_token == Token.IN || the_token == Token.OUT) {
the_token = token (); the_token = token ();
@ -1319,7 +1337,7 @@ namespace Mono.CSharp
bool seen_digits = false; bool seen_digits = false;
if (c != -1){ if (c != -1){
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) c; number_builder [number_pos++] = (char) c;
} }
@ -1330,7 +1348,7 @@ namespace Mono.CSharp
// //
while ((d = peek_char2 ()) != -1){ while ((d = peek_char2 ()) != -1){
if (d >= '0' && d <= '9'){ if (d >= '0' && d <= '9'){
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) d; number_builder [number_pos++] = (char) d;
get_char (); get_char ();
@ -1595,23 +1613,23 @@ namespace Mono.CSharp
if (c == 'e' || c == 'E'){ if (c == 'e' || c == 'E'){
is_real = true; is_real = true;
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = (char) c; number_builder [number_pos++] = (char) c;
c = get_char (); c = get_char ();
if (c == '+'){ if (c == '+'){
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = '+'; number_builder [number_pos++] = '+';
c = -1; c = -1;
} else if (c == '-') { } else if (c == '-') {
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = '-'; number_builder [number_pos++] = '-';
c = -1; c = -1;
} else { } else {
if (number_pos == max_number_size) if (number_pos == MaxNumberLength)
Error_NumericConstantTooLong (); Error_NumericConstantTooLong ();
number_builder [number_pos++] = '+'; number_builder [number_pos++] = '+';
} }
@ -1791,6 +1809,26 @@ namespace Mono.CSharp
return x; return x;
} }
int get_char_withwithoutskippingwindowseol ()
{
int x;
if (putback_char != -1) {
x = putback_char;
putback_char = -1;
} else {
x = reader.Read ();
}
if (x == '\r') {
} else if (x == '\n') {
advance_line ();
} else {
col++;
}
return x;
}
void advance_line () void advance_line ()
{ {
line++; line++;
@ -1817,12 +1855,9 @@ namespace Mono.CSharp
public void putback (int c) public void putback (int c)
{ {
if (putback_char != -1) { if (putback_char != -1) {
Console.WriteLine ("Col: " + col); throw new InternalErrorException (string.Format ("Secondary putback [{0}] putting back [{1}] is not allowed", (char)putback_char, (char) c), Location);
Console.WriteLine ("Row: " + line);
Console.WriteLine ("Name: " + current_source.Name);
Console.WriteLine ("Current [{0}] putting back [{1}] ", putback_char, c);
throw new Exception ("This should not happen putback on putback");
} }
if (c == '\n' || col == 0) { if (c == '\n' || col == 0) {
// It won't happen though. // It won't happen though.
line--; line--;
@ -1963,7 +1998,7 @@ namespace Mono.CSharp
} }
if (pos != 0) { if (pos != 0) {
if (pos > max_id_size) if (pos > MaxIdentifierLength)
arg = new string (value_builder, 0, pos); arg = new string (value_builder, 0, pos);
else else
arg = InternIdentifier (value_builder, pos); arg = InternIdentifier (value_builder, pos);
@ -1998,7 +2033,6 @@ namespace Mono.CSharp
} }
//ref_line = line; //ref_line = line;
Location.Push (current_source);
return true; return true;
} }
@ -2085,7 +2119,6 @@ namespace Mono.CSharp
if (new_file_name != null) { if (new_file_name != null) {
current_source = context.LookupFile (source_file, new_file_name); current_source = context.LookupFile (source_file, new_file_name);
source_file.AddIncludeFile (current_source); source_file.AddIncludeFile (current_source);
Location.Push (current_source);
} }
if (!hidden_block_start.IsNull) { if (!hidden_block_start.IsNull) {
@ -2183,6 +2216,8 @@ namespace Mono.CSharp
// //
// The syntax is ` "foo.txt" "{guid}" "hash"' // The syntax is ` "foo.txt" "{guid}" "hash"'
// //
// guid is predefined hash algorithm guid {406ea660-64cf-4c82-b6f0-42d48172a799} for md5
//
int c = get_char (); int c = get_char ();
if (c != '"') if (c != '"')
@ -2245,6 +2280,7 @@ namespace Mono.CSharp
// Any length of checksum // Any length of checksum
List<byte> checksum_bytes = new List<byte> (16); List<byte> checksum_bytes = new List<byte> (16);
var checksum_location = Location;
c = peek_char (); c = peek_char ();
while (c != '"' && c != -1) { while (c != '"' && c != -1) {
checksum_bytes.Add (read_hex (out error)); checksum_bytes.Add (read_hex (out error));
@ -2260,14 +2296,23 @@ namespace Mono.CSharp
return false; return false;
} }
file.SetChecksum (guid_bytes, checksum_bytes.ToArray ()); if (context.Settings.GenerateDebugInfo) {
var chsum = checksum_bytes.ToArray ();
if (file.HasChecksum) {
if (!ArrayComparer.IsEqual (file.Checksum, chsum)) {
// TODO: Report.SymbolRelatedToPreviousError
Report.Warning (1697, 1, checksum_location, "Different checksum values specified for file `{0}'", file.Name);
}
}
file.SetChecksum (guid_bytes, chsum);
current_source.AutoGenerated = true; current_source.AutoGenerated = true;
}
return true; return true;
} }
#if !FULL_AST
static
#endif
bool IsTokenIdentifierEqual (char[] identifier) bool IsTokenIdentifierEqual (char[] identifier)
{ {
for (int i = 0; i < identifier.Length; ++i) { for (int i = 0; i < identifier.Length; ++i) {
@ -2871,7 +2916,7 @@ namespace Mono.CSharp
#endif #endif
while (true){ while (true){
c = get_char (); c = get_char_withwithoutskippingwindowseol ();
if (c == '"') { if (c == '"') {
if (quoted && peek_char () == '"') { if (quoted && peek_char () == '"') {
if (pos == value_builder.Length) if (pos == value_builder.Length)
@ -3009,7 +3054,7 @@ namespace Mono.CSharp
if (id_builder [0] >= '_' && !quoted) { if (id_builder [0] >= '_' && !quoted) {
int keyword = GetKeyword (id_builder, pos); int keyword = GetKeyword (id_builder, pos);
if (keyword != -1) { if (keyword != -1) {
val = LocatedToken.Create (keyword == Token.AWAIT ? "await" : null, ref_line, column); val = ltb.Create (keyword == Token.AWAIT ? "await" : null, current_source, ref_line, column);
return keyword; return keyword;
} }
} }
@ -3017,12 +3062,12 @@ namespace Mono.CSharp
string s = InternIdentifier (id_builder, pos); string s = InternIdentifier (id_builder, pos);
#if FULL_AST #if FULL_AST
if (quoted) { if (quoted) {
val = LocatedToken.Create ("@" + s, ref_line, column - 1); val = ltb.Create ("@" + s, current_source, ref_line, column - 1);
} else { } else {
val = LocatedToken.Create (s, ref_line, column); val = ltb.Create (s, current_source, ref_line, column);
} }
#else #else
val = LocatedToken.Create (s, ref_line, column); val = ltb.Create (s, current_source, ref_line, column);
#endif #endif
if (quoted && parsing_attribute_section) if (quoted && parsing_attribute_section)
AddEscapedIdentifier (((LocatedToken) val).Location); AddEscapedIdentifier (((LocatedToken) val).Location);
@ -3030,9 +3075,6 @@ namespace Mono.CSharp
return Token.IDENTIFIER; return Token.IDENTIFIER;
} }
#if !FULL_AST
static
#endif
string InternIdentifier (char[] charBuffer, int length) string InternIdentifier (char[] charBuffer, int length)
{ {
// //
@ -3098,17 +3140,17 @@ namespace Mono.CSharp
return consume_identifier (c); return consume_identifier (c);
case '{': case '{':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
return Token.OPEN_BRACE; return Token.OPEN_BRACE;
case '}': case '}':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
return Token.CLOSE_BRACE; return Token.CLOSE_BRACE;
case '[': case '[':
// To block doccomment inside attribute declaration. // To block doccomment inside attribute declaration.
if (doc_state == XmlCommentState.Allowed) if (doc_state == XmlCommentState.Allowed)
doc_state = XmlCommentState.NotAllowed; doc_state = XmlCommentState.NotAllowed;
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (parsing_block == 0 || lambda_arguments_parsing) if (parsing_block == 0 || lambda_arguments_parsing)
return Token.OPEN_BRACKET; return Token.OPEN_BRACKET;
@ -3134,10 +3176,10 @@ namespace Mono.CSharp
return Token.OPEN_BRACKET_EXPR; return Token.OPEN_BRACKET_EXPR;
} }
case ']': case ']':
LocatedToken.CreateOptional (ref_line, col, ref val); ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.CLOSE_BRACKET; return Token.CLOSE_BRACKET;
case '(': case '(':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
// //
// An expression versions of parens can appear in block context only // An expression versions of parens can appear in block context only
// //
@ -3182,29 +3224,29 @@ namespace Mono.CSharp
return Token.OPEN_PARENS; return Token.OPEN_PARENS;
case ')': case ')':
LocatedToken.CreateOptional (ref_line, col, ref val); ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.CLOSE_PARENS; return Token.CLOSE_PARENS;
case ',': case ',':
LocatedToken.CreateOptional (ref_line, col, ref val); ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.COMMA; return Token.COMMA;
case ';': case ';':
LocatedToken.CreateOptional (ref_line, col, ref val); ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.SEMICOLON; return Token.SEMICOLON;
case '~': case '~':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
return Token.TILDE; return Token.TILDE;
case '?': case '?':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
return TokenizePossibleNullableType (); return TokenizePossibleNullableType ();
case '<': case '<':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (parsing_generic_less_than++ > 0) if (parsing_generic_less_than++ > 0)
return Token.OP_GENERICS_LT; return Token.OP_GENERICS_LT;
return TokenizeLessThan (); return TokenizeLessThan ();
case '>': case '>':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '=') { if (d == '=') {
@ -3231,7 +3273,7 @@ namespace Mono.CSharp
return Token.OP_GT; return Token.OP_GT;
case '+': case '+':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '+') { if (d == '+') {
d = Token.OP_INC; d = Token.OP_INC;
@ -3244,7 +3286,7 @@ namespace Mono.CSharp
return d; return d;
case '-': case '-':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '-') { if (d == '-') {
d = Token.OP_DEC; d = Token.OP_DEC;
@ -3259,7 +3301,7 @@ namespace Mono.CSharp
return d; return d;
case '!': case '!':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){ if (peek_char () == '='){
get_char (); get_char ();
return Token.OP_NE; return Token.OP_NE;
@ -3267,7 +3309,7 @@ namespace Mono.CSharp
return Token.BANG; return Token.BANG;
case '=': case '=':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '=') { if (d == '=') {
get_char (); get_char ();
@ -3281,7 +3323,7 @@ namespace Mono.CSharp
return Token.ASSIGN; return Token.ASSIGN;
case '&': case '&':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '&') { if (d == '&') {
get_char (); get_char ();
@ -3294,7 +3336,7 @@ namespace Mono.CSharp
return Token.BITWISE_AND; return Token.BITWISE_AND;
case '|': case '|':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
d = peek_char (); d = peek_char ();
if (d == '|') { if (d == '|') {
get_char (); get_char ();
@ -3307,7 +3349,7 @@ namespace Mono.CSharp
return Token.BITWISE_OR; return Token.BITWISE_OR;
case '*': case '*':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){ if (peek_char () == '='){
get_char (); get_char ();
return Token.OP_MULT_ASSIGN; return Token.OP_MULT_ASSIGN;
@ -3317,7 +3359,7 @@ namespace Mono.CSharp
case '/': case '/':
d = peek_char (); d = peek_char ();
if (d == '='){ if (d == '='){
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
get_char (); get_char ();
return Token.OP_DIV_ASSIGN; return Token.OP_DIV_ASSIGN;
} }
@ -3426,11 +3468,11 @@ namespace Mono.CSharp
update_formatted_doc_comment (current_comment_start); update_formatted_doc_comment (current_comment_start);
continue; continue;
} }
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
return Token.DIV; return Token.DIV;
case '%': case '%':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){ if (peek_char () == '='){
get_char (); get_char ();
return Token.OP_MOD_ASSIGN; return Token.OP_MOD_ASSIGN;
@ -3438,7 +3480,7 @@ namespace Mono.CSharp
return Token.PERCENT; return Token.PERCENT;
case '^': case '^':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (peek_char () == '='){ if (peek_char () == '='){
get_char (); get_char ();
return Token.OP_XOR_ASSIGN; return Token.OP_XOR_ASSIGN;
@ -3446,7 +3488,7 @@ namespace Mono.CSharp
return Token.CARRET; return Token.CARRET;
case ':': case ':':
val = LocatedToken.Create (ref_line, col); val = ltb.Create (current_source, ref_line, col);
if (peek_char () == ':') { if (peek_char () == ':') {
get_char (); get_char ();
return Token.DOUBLE_COLON; return Token.DOUBLE_COLON;
@ -3470,7 +3512,7 @@ namespace Mono.CSharp
if (d >= '0' && d <= '9') if (d >= '0' && d <= '9')
return is_number (c); return is_number (c);
LocatedToken.CreateOptional (ref_line, col, ref val); ltb.CreateOptional (current_source, ref_line, col, ref val);
return Token.DOT; return Token.DOT;
case '#': case '#':

11
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/decl.cs

@ -608,7 +608,7 @@ namespace Mono.CSharp {
if (al == Modifiers.PRIVATE) { if (al == Modifiers.PRIVATE) {
var decl = mc.Parent; var decl = mc.Parent;
do { do {
same_access_restrictions = decl.CurrentType == p_parent; same_access_restrictions = decl.CurrentType.MemberDefinition == p_parent.MemberDefinition;
} while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null); } while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null);
} }
@ -945,6 +945,15 @@ namespace Mono.CSharp {
GenericTask = 1 << 22 GenericTask = 1 << 22
} }
//
// Some flags can be copied directly from other member
//
protected const StateFlags SharedStateFlags =
StateFlags.CLSCompliant | StateFlags.CLSCompliant_Undetected |
StateFlags.Obsolete | StateFlags.Obsolete_Undetected |
StateFlags.MissingDependency | StateFlags.MissingDependency_Undetected |
StateFlags.HasDynamicElement;
protected Modifiers modifiers; protected Modifiers modifiers;
public StateFlags state; public StateFlags state;
protected IMemberDefinition definition; protected IMemberDefinition definition;

5
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/delegate.cs

@ -520,8 +520,11 @@ namespace Mono.CSharp {
} }
TypeSpec rt = delegate_method.ReturnType; TypeSpec rt = delegate_method.ReturnType;
if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
rt = ec.BuiltinTypes.Object;
if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) { if (!Delegate.IsTypeCovariant (ec, rt, invoke_method.ReturnType)) {
Expression ret_expr = new TypeExpression (rt, loc); Expression ret_expr = new TypeExpression (delegate_method.ReturnType, loc);
Error_ConversionFailed (ec, delegate_method, ret_expr); Error_ConversionFailed (ec, delegate_method, ret_expr);
} }

14
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/doc.cs

@ -47,6 +47,8 @@ namespace Mono.CSharp
// //
Dictionary<string, XmlDocument> StoredDocuments = new Dictionary<string, XmlDocument> (); Dictionary<string, XmlDocument> StoredDocuments = new Dictionary<string, XmlDocument> ();
ParserSession session;
public DocumentationBuilder (ModuleContainer module) public DocumentationBuilder (ModuleContainer module)
{ {
doc_module = new ModuleContainer (module.Compiler); doc_module = new ModuleContainer (module.Compiler);
@ -324,12 +326,18 @@ namespace Mono.CSharp
var encoding = module.Compiler.Settings.Encoding; var encoding = module.Compiler.Settings.Encoding;
var s = new MemoryStream (encoding.GetBytes (cref)); var s = new MemoryStream (encoding.GetBytes (cref));
SeekableStreamReader seekable = new SeekableStreamReader (s, encoding);
var source_file = new CompilationSourceFile (doc_module); var source_file = new CompilationSourceFile (doc_module, mc.Location.SourceFile);
var report = new Report (doc_module.Compiler, new NullReportPrinter ()); var report = new Report (doc_module.Compiler, new NullReportPrinter ());
var parser = new CSharpParser (seekable, source_file, report); if (session == null)
session = new ParserSession () {
UseJayGlobalArrays = true
};
SeekableStreamReader seekable = new SeekableStreamReader (s, encoding, session.StreamReaderBuffer);
var parser = new CSharpParser (seekable, source_file, report, session);
ParsedParameters = null; ParsedParameters = null;
ParsedName = null; ParsedName = null;
ParsedBuiltinType = null; ParsedBuiltinType = null;

73
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/driver.cs

@ -20,6 +20,7 @@ using System.IO;
using System.Text; using System.Text;
using System.Globalization; using System.Globalization;
using System.Diagnostics; using System.Diagnostics;
using System.Threading;
namespace Mono.CSharp namespace Mono.CSharp
{ {
@ -41,7 +42,7 @@ namespace Mono.CSharp
} }
} }
void tokenize_file (SourceFile sourceFile, ModuleContainer module) void tokenize_file (SourceFile sourceFile, ModuleContainer module, ParserSession session)
{ {
Stream input; Stream input;
@ -56,7 +57,7 @@ namespace Mono.CSharp
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding); SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
var file = new CompilationSourceFile (module, sourceFile); var file = new CompilationSourceFile (module, sourceFile);
Tokenizer lexer = new Tokenizer (reader, file); Tokenizer lexer = new Tokenizer (reader, file, session);
int token, tokens = 0, errors = 0; int token, tokens = 0, errors = 0;
while ((token = lexer.token ()) != Token.EOF){ while ((token = lexer.token ()) != Token.EOF){
@ -77,49 +78,97 @@ namespace Mono.CSharp
Location.Initialize (sources); Location.Initialize (sources);
var session = new ParserSession () {
UseJayGlobalArrays = true,
LocatedTokens = new Tokenizer.LocatedToken[15000]
};
for (int i = 0; i < sources.Count; ++i) { for (int i = 0; i < sources.Count; ++i) {
if (tokenize_only) { if (tokenize_only) {
tokenize_file (sources[i], module); tokenize_file (sources[i], module, session);
} else { } else {
Parse (sources[i], module); Parse (sources[i], module, session, Report);
} }
} }
} }
public void Parse (SourceFile file, ModuleContainer module) #if false
void ParseParallel (ModuleContainer module)
{
var sources = module.Compiler.SourceFiles;
Location.Initialize (sources);
var pcount = Environment.ProcessorCount;
var threads = new Thread[System.Math.Max (2, pcount - 1)];
for (int i = 0; i < threads.Length; ++i) {
var t = new Thread (l => {
var session = new ParserSession () {
//UseJayGlobalArrays = true,
};
var report = new Report (ctx, Report.Printer); // TODO: Implement flush at once printer
for (int ii = (int) l; ii < sources.Count; ii += threads.Length) {
Parse (sources[ii], module, session, report);
}
// TODO: Merge warning regions
});
t.Start (i);
threads[i] = t;
}
for (int t = 0; t < threads.Length; ++t) {
threads[t].Join ();
}
}
#endif
public void Parse (SourceFile file, ModuleContainer module, ParserSession session, Report report)
{ {
Stream input; Stream input;
try { try {
input = File.OpenRead (file.Name); input = File.OpenRead (file.Name);
} catch { } catch {
Report.Error (2001, "Source file `{0}' could not be found", file.Name); report.Error (2001, "Source file `{0}' could not be found", file.Name);
return; return;
} }
// Check 'MZ' header // Check 'MZ' header
if (input.ReadByte () == 77 && input.ReadByte () == 90) { if (input.ReadByte () == 77 && input.ReadByte () == 90) {
Report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name); report.Error (2015, "Source file `{0}' is a binary file and not a text file", file.Name);
input.Close (); input.Close ();
return; return;
} }
input.Position = 0; input.Position = 0;
SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding); SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding, session.StreamReaderBuffer);
Parse (reader, file, module, session, report);
if (ctx.Settings.GenerateDebugInfo && report.Errors == 0 && !file.HasChecksum) {
input.Position = 0;
var checksum = session.GetChecksumAlgorithm ();
file.SetChecksum (checksum.ComputeHash (input));
}
Parse (reader, file, module);
reader.Dispose (); reader.Dispose ();
input.Close (); input.Close ();
} }
public static CSharpParser Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, int lineModifier = 0) public static CSharpParser Parse (SeekableStreamReader reader, SourceFile sourceFile, ModuleContainer module, ParserSession session, Report report, int lineModifier = 0, int colModifier = 0)
{ {
var file = new CompilationSourceFile (module, sourceFile); var file = new CompilationSourceFile (module, sourceFile);
module.AddTypeContainer(file); module.AddTypeContainer(file);
CSharpParser parser = new CSharpParser (reader, file); CSharpParser parser = new CSharpParser (reader, file, report, session);
parser.Lexer.Line += lineModifier; parser.Lexer.Line += lineModifier;
parser.Lexer.Column += colModifier;
parser.Lexer.sbag = new SpecialsBag (); parser.Lexer.sbag = new SpecialsBag ();
parser.parse (); parser.parse ();
return parser; return parser;
@ -347,6 +396,7 @@ namespace Mono.CSharp
tr.Stop (TimeReporter.TimerType.CloseTypes); tr.Stop (TimeReporter.TimerType.CloseTypes);
tr.Start (TimeReporter.TimerType.Resouces); tr.Start (TimeReporter.TimerType.Resouces);
if (!settings.WriteMetadataOnly)
assembly.EmbedResources (); assembly.EmbedResources ();
tr.Stop (TimeReporter.TimerType.Resouces); tr.Stop (TimeReporter.TimerType.Resouces);
@ -369,6 +419,7 @@ namespace Mono.CSharp
public ModuleContainer ModuleCompiled { get; set; } public ModuleContainer ModuleCompiled { get; set; }
public LocationsBag LocationsBag { get; set; } public LocationsBag LocationsBag { get; set; }
public SpecialsBag SpecialsBag { get; set; } public SpecialsBag SpecialsBag { get; set; }
public IEnumerable<string> Conditionals { get; set; }
public object LastYYValue { get; set; } public object LastYYValue { get; set; }
} }

2
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/dynamic.cs

@ -502,7 +502,7 @@ namespace Mono.CSharp
using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
if (s.Resolve (bc)) { if (s.Resolve (bc)) {
Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc), loc), s, loc); Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
init.Emit (ec); init.Emit (ec);
} }

239
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs

@ -2277,9 +2277,11 @@ namespace Mono.CSharp {
} }
} }
var report = ctx.Module.Compiler.Report;
var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc); var retval = ctx.LookupNamespaceOrType (Name, Arity, LookupMode.IgnoreAccessibility, loc);
if (retval != null) { if (retval != null) {
ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (retval.Type); report.SymbolRelatedToPreviousError (retval.Type);
ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc); ErrorIsInaccesible (ctx, retval.GetSignatureForError (), loc);
return; return;
} }
@ -2290,7 +2292,17 @@ namespace Mono.CSharp {
return; return;
} }
NamespaceContainer.Error_NamespaceNotFound (loc, Name, ctx.Module.Compiler.Report); var ns_candidates = ctx.Module.GlobalRootNamespace.FindTypeNamespaces (ctx, Name, Arity);
if (ns_candidates != null) {
string usings = string.Join ("' or `", ns_candidates.ToArray ());
report.Error (246, loc,
"The type or namespace name `{0}' could not be found. Are you missing `{1}' using directive?",
Name, usings);
} else {
report.Error (246, loc,
"The type or namespace name `{0}' could not be found. Are you missing an assembly reference?",
Name);
}
} }
public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec) public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
@ -2401,7 +2413,7 @@ namespace Mono.CSharp {
} else { } else {
break; break;
} }
} else if (me is MethodGroupExpr) { } else if (me is MethodGroupExpr || me is PropertyExpr || me is IndexerExpr) {
// Leave it to overload resolution to report correct error // Leave it to overload resolution to report correct error
} else { } else {
// TODO: rc.Report.SymbolRelatedToPreviousError () // TODO: rc.Report.SymbolRelatedToPreviousError ()
@ -2777,8 +2789,14 @@ namespace Mono.CSharp {
} }
} }
// TODO: For now we do it for any hoisted call even if it's needed for //
// hoisted stories only but that requires a new expression wrapper // When base access is used inside anonymous method/iterator/etc we need to
// get back to the context of original type. We do it by emiting proxy
// method in original class and rewriting base call to this compiler
// generated method call which does the actual base invocation. This may
// introduce redundant storey but with `this' only but it's tricky to avoid
// at this stage as we don't know what expressions follow base
//
if (rc.CurrentAnonymousMethod != null) { if (rc.CurrentAnonymousMethod != null) {
if (targs == null && method.IsGeneric) { if (targs == null && method.IsGeneric) {
targs = method.TypeArguments; targs = method.TypeArguments;
@ -2792,8 +2810,9 @@ namespace Mono.CSharp {
// Ideally this should apply to any proxy rewrite but in the case of unary mutators on // Ideally this should apply to any proxy rewrite but in the case of unary mutators on
// get/set member expressions second call would fail to proxy because left expression // get/set member expressions second call would fail to proxy because left expression
// would be of 'this' and not 'base' // would be of 'this' and not 'base' because we share InstanceExpression for get/set
if (rc.CurrentType.IsStruct) // FIXME: The async check is another hack but will probably fail with mutators
if (rc.CurrentType.IsStruct || rc.CurrentAnonymousMethod.Storey is AsyncTaskStorey)
InstanceExpression = new This (loc).Resolve (rc); InstanceExpression = new This (loc).Resolve (rc);
} }
@ -2967,7 +2986,7 @@ namespace Mono.CSharp {
"An object reference is required to access non-static member `{0}'", "An object reference is required to access non-static member `{0}'",
GetSignatureForError ()); GetSignatureForError ());
InstanceExpression = new CompilerGeneratedThis (type, loc).Resolve (rc); InstanceExpression = new CompilerGeneratedThis (rc.CurrentType, loc).Resolve (rc);
return false; return false;
} }
@ -2993,6 +3012,8 @@ namespace Mono.CSharp {
if (me != null) { if (me != null) {
me.ResolveInstanceExpression (rc, rhs); me.ResolveInstanceExpression (rc, rhs);
// Using this check to detect probing instance expression resolve
if (!rc.OmitStructFlowAnalysis) {
var fe = me as FieldExpr; var fe = me as FieldExpr;
if (fe != null && fe.IsMarshalByRefAccess (rc)) { if (fe != null && fe.IsMarshalByRefAccess (rc)) {
rc.Report.SymbolRelatedToPreviousError (me.DeclaringType); rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
@ -3000,6 +3021,7 @@ namespace Mono.CSharp {
"Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class", "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
me.GetSignatureForError ()); me.GetSignatureForError ());
} }
}
return true; return true;
} }
@ -3166,8 +3188,12 @@ namespace Mono.CSharp {
} }
var me = ExtensionExpression as MemberExpr; var me = ExtensionExpression as MemberExpr;
if (me != null) if (me != null) {
me.ResolveInstanceExpression (ec, null); me.ResolveInstanceExpression (ec, null);
var fe = me as FieldExpr;
if (fe != null)
fe.Spec.MemberDefinition.SetIsUsed ();
}
InstanceExpression = null; InstanceExpression = null;
return this; return this;
@ -3437,11 +3463,35 @@ namespace Mono.CSharp {
best_candidate_return = best_candidate.ReturnType; best_candidate_return = best_candidate.ReturnType;
} }
if (best_candidate.IsGeneric && TypeParameterSpec.HasAnyTypeParameterConstrained (best_candidate.GenericDefinition)) {
ConstraintChecker cc = new ConstraintChecker (ec);
cc.CheckAll (best_candidate.GetGenericMethodDefinition (), best_candidate.TypeArguments, best_candidate.Constraints, loc);
}
//
// Additional check for possible imported base override method which
// could not be done during IsOverrideMethodBaseTypeAccessible
//
if (best_candidate.IsVirtual && (best_candidate.DeclaringType.Modifiers & Modifiers.PROTECTED) != 0 &&
best_candidate.MemberDefinition.IsImported && !best_candidate.DeclaringType.IsAccessible (ec)) {
ec.Report.SymbolRelatedToPreviousError (best_candidate);
ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
}
return this; return this;
} }
public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original) public override MemberExpr ResolveMemberAccess (ResolveContext ec, Expression left, SimpleName original)
{ {
var fe = left as FieldExpr;
if (fe != null) {
//
// Using method-group on struct fields makes the struct assigned. I am not sure
// why but that's what .net does
//
fe.Spec.MemberDefinition.SetIsAssigned ();
}
simple_name = original; simple_name = original;
return base.ResolveMemberAccess (ec, left, original); return base.ResolveMemberAccess (ec, left, original);
} }
@ -3587,7 +3637,6 @@ namespace Mono.CSharp {
TypeSpec best_candidate_return_type; TypeSpec best_candidate_return_type;
SessionReportPrinter lambda_conv_msgs; SessionReportPrinter lambda_conv_msgs;
ReportPrinter prev_recorder;
public OverloadResolver (IList<MemberSpec> members, Restrictions restrictions, Location loc) public OverloadResolver (IList<MemberSpec> members, Restrictions restrictions, Location loc)
: this (members, null, restrictions, loc) : this (members, null, restrictions, loc)
@ -3720,7 +3769,9 @@ namespace Mono.CSharp {
if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types)) if (!TypeSpecComparer.Equals (p_m.Parameters.Types, q_m.Parameters.Types))
return 0; return 0;
var orig_p = p;
p = p_m.ReturnType; p = p_m.ReturnType;
var orig_q = q;
q = q_m.ReturnType; q = q_m.ReturnType;
// //
@ -3737,14 +3788,14 @@ namespace Mono.CSharp {
return p.Kind != MemberKind.Void ? 1: 0; return p.Kind != MemberKind.Void ? 1: 0;
} }
var am = (AnonymousMethodExpression) a.Expr;
// //
// When anonymous method is an asynchronous, and P has a return type Task<Y1>, and Q has a return type Task<Y2> // When anonymous method is an asynchronous, and P has a return type Task<Y1>, and Q has a return type Task<Y2>
// better conversion is performed between underlying types Y1 and Y2 // better conversion is performed between underlying types Y1 and Y2
// //
if (p.IsGenericTask || q.IsGenericTask) { if (p.IsGenericTask || q.IsGenericTask) {
var async_am = a.Expr as AnonymousMethodExpression; if (am.Block.IsAsync) {
if (async_am != null && async_am.Block.IsAsync) {
if (p.IsGenericTask != q.IsGenericTask) { if (p.IsGenericTask != q.IsGenericTask) {
return 0; return 0;
} }
@ -3752,6 +3803,19 @@ namespace Mono.CSharp {
q = q.TypeArguments[0]; q = q.TypeArguments[0];
p = p.TypeArguments[0]; p = p.TypeArguments[0];
} }
} else if (q != p) {
//
// LAMESPEC: Lambda expression returning dynamic type has identity (better) conversion to delegate returning object type
//
if (q.BuiltinType == BuiltinTypeSpec.Type.Object) {
var am_rt = am.InferReturnType (ec, null, orig_q);
if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
return 2;
} else if (p.BuiltinType == BuiltinTypeSpec.Type.Object) {
var am_rt = am.InferReturnType (ec, null, orig_p);
if (am_rt != null && am_rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
return 1;
}
} }
// //
@ -4030,6 +4094,32 @@ namespace Mono.CSharp {
return false; return false;
} }
static bool CheckInflatedArguments (MethodSpec ms)
{
if (!TypeParameterSpec.HasAnyTypeParameterTypeConstrained (ms.GenericDefinition))
return true;
// Setup constraint checker for probing only
ConstraintChecker cc = new ConstraintChecker (null);
var mp = ms.Parameters.Types;
for (int i = 0; i < mp.Length; ++i) {
var type = mp[i] as InflatedTypeSpec;
if (type == null)
continue;
var targs = type.TypeArguments;
if (targs.Length == 0)
continue;
// TODO: Checking inflated MVAR arguments should be enough
if (!cc.CheckAll (type.GetDefinition (), targs, type.Constraints, Location.Null))
return false;
}
return true;
}
public static void Error_ConstructorMismatch (ResolveContext rc, TypeSpec type, int argCount, Location loc) public static void Error_ConstructorMismatch (ResolveContext rc, TypeSpec type, int argCount, Location loc)
{ {
rc.Report.Error (1729, loc, rc.Report.Error (1729, loc,
@ -4045,6 +4135,7 @@ namespace Mono.CSharp {
// //
// A return value rates candidate method compatibility, // A return value rates candidate method compatibility,
// 0 = the best, int.MaxValue = the worst // 0 = the best, int.MaxValue = the worst
// -1 = fatal error
// //
int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType) int IsApplicable (ResolveContext ec, ref Arguments arguments, int arg_count, ref MemberSpec candidate, IParametersMember pm, ref bool params_expanded_form, ref bool dynamicArgument, ref TypeSpec returnType)
{ {
@ -4166,15 +4257,24 @@ namespace Mono.CSharp {
arg_count = arguments.Count; arg_count = arguments.Count;
} }
//
// Don't do any expensive checks when the candidate cannot succeed
//
if (arg_count != param_count && !cpd.HasParams)
return (param_count - arg_count) * 2 + 1;
var dep = candidate.GetMissingDependencies ();
if (dep != null) {
ImportedTypeDefinition.Error_MissingDependency (ec, dep, loc);
return -1;
}
// //
// 1. Handle generic method using type arguments when specified or type inference // 1. Handle generic method using type arguments when specified or type inference
// //
TypeSpec[] ptypes; TypeSpec[] ptypes;
var ms = candidate as MethodSpec; var ms = candidate as MethodSpec;
if (ms != null && ms.IsGeneric) { if (ms != null && ms.IsGeneric) {
// Setup constraint checker for probing only
ConstraintChecker cc = new ConstraintChecker (null);
if (type_arguments != null) { if (type_arguments != null) {
var g_args_count = ms.Arity; var g_args_count = ms.Arity;
if (g_args_count != type_arguments.Count) if (g_args_count != type_arguments.Count)
@ -4182,31 +4282,50 @@ namespace Mono.CSharp {
ms = ms.MakeGenericMethod (ec, type_arguments.Arguments); ms = ms.MakeGenericMethod (ec, type_arguments.Arguments);
} else { } else {
// TODO: It should not be here (we don't know yet whether any argument is lambda) but //
// for now it simplifies things. I should probably add a callback to ResolveContext // Deploy custom error reporting for infered anonymous expression or lambda methods. When
// probing lambda methods keep all errors reported in separate set and once we are done and no best
// candidate was found use the set to report more details about what was wrong with lambda body.
// The general idea is to distinguish between code errors and errors caused by
// trial-and-error type inference
//
if (lambda_conv_msgs == null) { if (lambda_conv_msgs == null) {
for (int i = 0; i < arg_count; i++) {
Argument a = arguments[i];
if (a == null)
continue;
var am = a.Expr as AnonymousMethodExpression;
if (am != null) {
if (lambda_conv_msgs == null)
lambda_conv_msgs = new SessionReportPrinter (); lambda_conv_msgs = new SessionReportPrinter ();
prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
am.TypeInferenceReportPrinter = lambda_conv_msgs;
}
}
} }
var ti = new TypeInference (arguments); var ti = new TypeInference (arguments);
TypeSpec[] i_args = ti.InferMethodArguments (ec, ms); TypeSpec[] i_args = ti.InferMethodArguments (ec, ms);
lambda_conv_msgs.EndSession ();
if (i_args == null) if (i_args == null)
return ti.InferenceScore - 20000; return ti.InferenceScore - 20000;
//
// Clear any error messages when the result was success
//
if (lambda_conv_msgs != null)
lambda_conv_msgs.ClearSession ();
if (i_args.Length != 0) { if (i_args.Length != 0) {
ms = ms.MakeGenericMethod (ec, i_args); ms = ms.MakeGenericMethod (ec, i_args);
} }
cc.IgnoreInferredDynamic = true;
} }
// //
// Type arguments constraints have to match for the method to be applicable // Type arguments constraints have to match for the method to be applicable
// //
if (!cc.CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc)) { if (!CheckInflatedArguments (ms)) {
candidate = ms; candidate = ms;
return int.MaxValue - 25000; return int.MaxValue - 25000;
} }
@ -4403,28 +4522,11 @@ namespace Mono.CSharp {
if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0) if (argument.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic && (restrictions & Restrictions.CovariantDelegate) == 0)
return -1; return -1;
//
// Deploy custom error reporting for lambda methods. When probing lambda methods
// keep all errors reported in separate set and once we are done and no best
// candidate was found, this set is used to report more details about what was wrong
// with lambda body
//
if (argument.Expr.Type == InternalType.AnonymousMethod) {
if (lambda_conv_msgs == null) {
lambda_conv_msgs = new SessionReportPrinter ();
prev_recorder = ec.Report.SetPrinter (lambda_conv_msgs);
}
}
// //
// Use implicit conversion in all modes to return same candidates when the expression // Use implicit conversion in all modes to return same candidates when the expression
// is used as argument or delegate conversion // is used as argument or delegate conversion
// //
if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) { if (!Convert.ImplicitConversionExists (ec, argument.Expr, parameter)) {
if (lambda_conv_msgs != null) {
lambda_conv_msgs.EndSession ();
}
return 2; return 2;
} }
} }
@ -4450,7 +4552,7 @@ namespace Mono.CSharp {
return p; return p;
if (specific == ac_q.Element) if (specific == ac_q.Element)
return q; return q;
} else if (TypeManager.IsGenericType (p)) { } else if (p.IsGeneric && q.IsGeneric) {
var pargs = TypeManager.GetTypeArguments (p); var pargs = TypeManager.GetTypeArguments (p);
var qargs = TypeManager.GetTypeArguments (q); var qargs = TypeManager.GetTypeArguments (q);
@ -4494,14 +4596,11 @@ namespace Mono.CSharp {
bool error_mode = false; bool error_mode = false;
MemberSpec invocable_member = null; MemberSpec invocable_member = null;
// Be careful, cannot return until error reporter is restored
while (true) { while (true) {
best_candidate = null; best_candidate = null;
best_candidate_rate = int.MaxValue; best_candidate_rate = int.MaxValue;
var type_members = members; var type_members = members;
try {
do { do {
for (int i = 0; i < type_members.Count; ++i) { for (int i = 0; i < type_members.Count; ++i) {
var member = type_members[i]; var member = type_members[i];
@ -4556,10 +4655,18 @@ namespace Mono.CSharp {
TypeSpec rt = pm.MemberType; TypeSpec rt = pm.MemberType;
int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt); int candidate_rate = IsApplicable (rc, ref candidate_args, args_count, ref member, pm, ref params_expanded_form, ref dynamic_argument, ref rt);
if (lambda_conv_msgs != null)
lambda_conv_msgs.EndSession ();
// //
// How does it score compare to others // How does it score compare to others
// //
if (candidate_rate < best_candidate_rate) { if (candidate_rate < best_candidate_rate) {
// Fatal error (missing dependency), cannot continue
if (candidate_rate < 0)
return null;
best_candidate_rate = candidate_rate; best_candidate_rate = candidate_rate;
best_candidate = member; best_candidate = member;
best_candidate_args = candidate_args; best_candidate_args = candidate_args;
@ -4631,10 +4738,6 @@ namespace Mono.CSharp {
candidate_args = args; candidate_args = args;
} }
} while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null); } while (best_candidate_rate != 0 && (type_members = base_provider.GetBaseMembers (type_members[0].DeclaringType.BaseType)) != null);
} finally {
if (prev_recorder != null)
rc.Report.SetPrinter (prev_recorder);
}
// //
// We've found exact match // We've found exact match
@ -4685,6 +4788,17 @@ namespace Mono.CSharp {
args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError ()); args [0].Type.GetSignatureForError (), best_candidate.Name, best_candidate.GetSignatureForError ());
} }
//
// Check type constraints only when explicit type arguments are used
//
if (best_candidate.IsGeneric && type_arguments != null) {
MethodSpec bc = best_candidate as MethodSpec;
if (bc != null && TypeParameterSpec.HasAnyTypeParameterConstrained (bc.GenericDefinition)) {
ConstraintChecker cc = new ConstraintChecker (rc);
cc.CheckAll (bc.GetGenericMethodDefinition (), bc.TypeArguments, bc.Constraints, loc);
}
}
BestCandidateIsDynamic = true; BestCandidateIsDynamic = true;
return null; return null;
} }
@ -4744,11 +4858,6 @@ namespace Mono.CSharp {
if (oa != null && !rc.IsObsolete) if (oa != null && !rc.IsObsolete)
AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report); AttributeTester.Report_ObsoleteMessage (oa, best_candidate.GetSignatureForError (), loc, rc.Report);
var dep = best_candidate.GetMissingDependencies ();
if (dep != null) {
ImportedTypeDefinition.Error_MissingDependency (rc, dep, loc);
}
best_candidate.MemberDefinition.SetIsUsed (); best_candidate.MemberDefinition.SetIsUsed ();
args = best_candidate_args; args = best_candidate_args;
@ -4825,8 +4934,7 @@ namespace Mono.CSharp {
return; return;
} }
if (lambda_conv_msgs != null) { if (lambda_conv_msgs != null && lambda_conv_msgs.Merge (rc.Report.Printer)) {
if (lambda_conv_msgs.Merge (rc.Report.Printer))
return; return;
} }
@ -5217,14 +5325,25 @@ namespace Mono.CSharp {
public override Expression CreateExpressionTree (ResolveContext ec) public override Expression CreateExpressionTree (ResolveContext ec)
{ {
return CreateExpressionTree (ec, true);
}
public Expression CreateExpressionTree (ResolveContext ec, bool convertInstance)
{
Arguments args;
Expression instance; Expression instance;
if (InstanceExpression == null) { if (InstanceExpression == null) {
instance = new NullLiteral (loc); instance = new NullLiteral (loc);
} else { } else if (convertInstance) {
instance = InstanceExpression.CreateExpressionTree (ec); instance = InstanceExpression.CreateExpressionTree (ec);
} else {
args = new Arguments (1);
args.Add (new Argument (InstanceExpression));
instance = CreateExpressionFactoryCall (ec, "Constant", args);
} }
Arguments args = Arguments.CreateForExpressionTree (ec, null, args = Arguments.CreateForExpressionTree (ec, null,
instance, instance,
CreateTypeOfExpression ()); CreateTypeOfExpression ());
@ -5238,6 +5357,8 @@ namespace Mono.CSharp {
protected override Expression DoResolve (ResolveContext ec) protected override Expression DoResolve (ResolveContext ec)
{ {
spec.MemberDefinition.SetIsUsed ();
return DoResolve (ec, null); return DoResolve (ec, null);
} }
@ -5457,8 +5578,6 @@ namespace Mono.CSharp {
{ {
bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0; bool is_volatile = (spec.Modifiers & Modifiers.VOLATILE) != 0;
spec.MemberDefinition.SetIsUsed ();
if (IsStatic){ if (IsStatic){
if (is_volatile) if (is_volatile)
ec.Emit (OpCodes.Volatile); ec.Emit (OpCodes.Volatile);
@ -6046,7 +6165,7 @@ namespace Mono.CSharp {
GetSignatureForError ()); GetSignatureForError ());
} else { } else {
rc.Report.SymbolRelatedToPreviousError (best_candidate.Set); rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
ErrorIsInaccesible (rc, best_candidate.Set.GetSignatureForError (), loc); ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
} }
} }

11
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/eval.cs

@ -79,7 +79,7 @@ namespace Mono.CSharp
module = new ModuleContainer (ctx); module = new ModuleContainer (ctx);
module.Evaluator = this; module.Evaluator = this;
source_file = new CompilationSourceFile (module); source_file = new CompilationSourceFile (module, null);
module.AddTypeContainer (source_file); module.AddTypeContainer (source_file);
startup_files = ctx.SourceFiles.Count; startup_files = ctx.SourceFiles.Count;
@ -115,9 +115,10 @@ namespace Mono.CSharp
Location.Initialize (ctx.SourceFiles); Location.Initialize (ctx.SourceFiles);
var parser_session = new ParserSession ();
for (int i = 0; i < startup_files; ++i) { for (int i = 0; i < startup_files; ++i) {
var sf = ctx.SourceFiles [i]; var sf = ctx.SourceFiles [i];
d.Parse (sf, module); d.Parse (sf, module, parser_session, ctx.Report);
} }
} }
@ -442,7 +443,7 @@ namespace Mono.CSharp
// //
InputKind ToplevelOrStatement (SeekableStreamReader seekable) InputKind ToplevelOrStatement (SeekableStreamReader seekable)
{ {
Tokenizer tokenizer = new Tokenizer (seekable, source_file); Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ());
int t = tokenizer.token (); int t = tokenizer.token ();
switch (t){ switch (t){
@ -571,7 +572,7 @@ namespace Mono.CSharp
seekable.Position = 0; seekable.Position = 0;
source_file.DeclarationFound = false; source_file.DeclarationFound = false;
CSharpParser parser = new CSharpParser (seekable, source_file); CSharpParser parser = new CSharpParser (seekable, source_file, new ParserSession ());
if (kind == InputKind.StatementOrExpression){ if (kind == InputKind.StatementOrExpression){
parser.Lexer.putback_char = Tokenizer.EvalStatementParserCharacter; parser.Lexer.putback_char = Tokenizer.EvalStatementParserCharacter;
@ -976,7 +977,9 @@ namespace Mono.CSharp
static public string help { static public string help {
get { get {
return "Static methods:\n" + return "Static methods:\n" +
#if !NET_2_1
" Describe (object); - Describes the object's type\n" + " Describe (object); - Describes the object's type\n" +
#endif
" LoadPackage (package); - Loads the given Package (like -pkg:FILE)\n" + " LoadPackage (package); - Loads the given Package (like -pkg:FILE)\n" +
" LoadAssembly (assembly); - Loads the given assembly (like -r:ASSEMBLY)\n" + " LoadAssembly (assembly); - Loads the given assembly (like -r:ASSEMBLY)\n" +
" ShowVars (); - Shows defined local variables.\n" + " ShowVars (); - Shows defined local variables.\n" +

72
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs

@ -1211,7 +1211,7 @@ namespace Mono.CSharp
var one = new IntConstant (ec.BuiltinTypes, 1, loc); var one = new IntConstant (ec.BuiltinTypes, 1, loc);
var op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition; var op = IsDecrement ? Binary.Operator.Subtraction : Binary.Operator.Addition;
operation = new Binary (op, source, one, loc); operation = new Binary (op, source, one);
operation = operation.Resolve (ec); operation = operation.Resolve (ec);
if (operation == null) if (operation == null)
throw new NotImplementedException ("should not be reached"); throw new NotImplementedException ("should not be reached");
@ -1527,7 +1527,7 @@ namespace Mono.CSharp
// Turn is check into simple null check for implicitly convertible reference types // Turn is check into simple null check for implicitly convertible reference types
// //
return ReducedExpression.Create ( return ReducedExpression.Create (
new Binary (Binary.Operator.Inequality, expr, new NullLiteral (loc), loc).Resolve (ec), new Binary (Binary.Operator.Inequality, expr, new NullLiteral (loc)).Resolve (ec),
this).Resolve (ec); this).Resolve (ec);
} }
@ -2014,7 +2014,7 @@ namespace Mono.CSharp
// b = b.left >> b.right & (0x1f|0x3f) // b = b.left >> b.right & (0x1f|0x3f)
// //
b.right = new Binary (Operator.BitwiseAnd, b.right = new Binary (Operator.BitwiseAnd,
b.right, new IntConstant (ec.BuiltinTypes, right_mask, b.right.Location), b.loc).Resolve (ec); b.right, new IntConstant (ec.BuiltinTypes, right_mask, b.right.Location)).Resolve (ec);
// //
// Expression tree representation does not use & mask // Expression tree representation does not use & mask
@ -2202,19 +2202,19 @@ namespace Mono.CSharp
protected State state; protected State state;
Expression enum_conversion; Expression enum_conversion;
public Binary (Operator oper, Expression left, Expression right, bool isCompound, Location loc) public Binary (Operator oper, Expression left, Expression right, bool isCompound)
: this (oper, left, right, loc) : this (oper, left, right)
{ {
if (isCompound) if (isCompound)
state |= State.Compound; state |= State.Compound;
} }
public Binary (Operator oper, Expression left, Expression right, Location loc) public Binary (Operator oper, Expression left, Expression right)
{ {
this.oper = oper; this.oper = oper;
this.left = left; this.left = left;
this.right = right; this.right = right;
this.loc = loc; this.loc = left.Location;
} }
#region Properties #region Properties
@ -2319,7 +2319,7 @@ namespace Mono.CSharp
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, Operator oper, Location loc) public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, Operator oper, Location loc)
{ {
new Binary (oper, left, right, loc).Error_OperatorCannotBeApplied (ec, left, right); new Binary (oper, left, right).Error_OperatorCannotBeApplied (ec, left, right);
} }
public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, string oper, Location loc) public static void Error_OperatorCannotBeApplied (ResolveContext ec, Expression left, Expression right, string oper, Location loc)
@ -3031,7 +3031,7 @@ namespace Mono.CSharp
(TypeSpec.IsValueType (left.Type) && right is NullLiteral) || (TypeSpec.IsValueType (left.Type) && right is NullLiteral) ||
(right.Type.IsNullableType && (left is NullLiteral || left.Type.IsNullableType || TypeSpec.IsValueType (left.Type))) || (right.Type.IsNullableType && (left is NullLiteral || left.Type.IsNullableType || TypeSpec.IsValueType (left.Type))) ||
(TypeSpec.IsValueType (right.Type) && left is NullLiteral))) { (TypeSpec.IsValueType (right.Type) && left is NullLiteral))) {
var lifted = new Nullable.LiftedBinaryOperator (oper, left, right, loc); var lifted = new Nullable.LiftedBinaryOperator (oper, left, right);
lifted.state = state; lifted.state = state;
return lifted.Resolve (ec); return lifted.Resolve (ec);
} }
@ -4409,7 +4409,7 @@ namespace Mono.CSharp
// TODO: Should be the checks resolve context sensitive? // TODO: Should be the checks resolve context sensitive?
ResolveContext rc = new ResolveContext (ec.MemberContext, ResolveContext.Options.UnsafeScope); ResolveContext rc = new ResolveContext (ec.MemberContext, ResolveContext.Options.UnsafeScope);
right = new Binary (Binary.Operator.Multiply, right, right_const, loc).Resolve (rc); right = new Binary (Binary.Operator.Multiply, right, right_const).Resolve (rc);
if (right == null) if (right == null)
return; return;
} }
@ -5264,8 +5264,10 @@ namespace Mono.CSharp
{ {
this.expr = expr; this.expr = expr;
this.arguments = arguments; this.arguments = arguments;
if (expr != null) if (expr != null) {
loc = expr.Location; var ma = expr as MemberAccess;
loc = ma != null ? ma.GetLeftExpressionLocation () : expr.Location;
}
} }
#region Properties #region Properties
@ -6154,7 +6156,7 @@ namespace Mono.CSharp
{ {
if (initializers != null && bounds == null) { if (initializers != null && bounds == null) {
// //
// We use this to store all the date values in the order in which we // We use this to store all the data values in the order in which we
// will need to store them in the byte blob later // will need to store them in the byte blob later
// //
array_data = new List<Expression> (); array_data = new List<Expression> ();
@ -6213,6 +6215,15 @@ namespace Mono.CSharp
return false; return false;
} }
// When we don't have explicitly specified dimensions, record whatever dimension we first encounter at each level
if (!bounds.ContainsKey(idx + 1))
bounds[idx + 1] = sub_probe.Count;
if (bounds[idx + 1] != sub_probe.Count) {
ec.Report.Error(847, sub_probe.Location, "An array initializer of length `{0}' was expected", bounds[idx + 1].ToString());
return false;
}
bool ret = CheckIndices (ec, sub_probe, idx + 1, specified_dims, child_bounds - 1); bool ret = CheckIndices (ec, sub_probe, idx + 1, specified_dims, child_bounds - 1);
if (!ret) if (!ret)
return false; return false;
@ -6987,7 +6998,7 @@ namespace Mono.CSharp
if (variable_info == null) if (variable_info == null)
return; return;
if (rc.HasSet (ResolveContext.Options.OmitStructFlowAnalysis)) if (rc.OmitStructFlowAnalysis)
return; return;
if (!variable_info.IsAssigned (rc)) { if (!variable_info.IsAssigned (rc)) {
@ -7932,6 +7943,18 @@ namespace Mono.CSharp
expr.Error_OperatorCannotBeApplied (rc, loc, ".", type); expr.Error_OperatorCannotBeApplied (rc, loc, ".", type);
} }
public Location GetLeftExpressionLocation ()
{
Expression expr = LeftExpression;
MemberAccess ma = expr as MemberAccess;
while (ma != null && ma.LeftExpression != null) {
expr = ma.LeftExpression;
ma = expr as MemberAccess;
}
return expr == null ? Location : expr.Location;
}
public static bool IsValidDotExpression (TypeSpec type) public static bool IsValidDotExpression (TypeSpec type)
{ {
const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum | const MemberKind dot_kinds = MemberKind.Class | MemberKind.Struct | MemberKind.Delegate | MemberKind.Enum |
@ -8252,9 +8275,19 @@ namespace Mono.CSharp
{ {
if (ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2 && !ec.IsRuntimeBinder && MethodGroupExpr.IsExtensionMethodArgument (expr)) { if (ec.Module.Compiler.Settings.Version > LanguageVersion.ISO_2 && !ec.IsRuntimeBinder && MethodGroupExpr.IsExtensionMethodArgument (expr)) {
ec.Report.SymbolRelatedToPreviousError (type); ec.Report.SymbolRelatedToPreviousError (type);
var cand = ec.Module.GlobalRootNamespace.FindExtensionMethodNamespaces (ec, type, name, Arity);
string missing;
// a using directive or an assembly reference
if (cand != null) {
missing = "`" + string.Join ("' or `", cand.ToArray ()) + "' using directive";
} else {
missing = "an assembly reference";
}
ec.Report.Error (1061, loc, ec.Report.Error (1061, loc,
"Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found (are you missing a using directive or an assembly reference?)", "Type `{0}' does not contain a definition for `{1}' and no extension method `{1}' of type `{0}' could be found. Are you missing {2}?",
type.GetSignatureForError (), name); type.GetSignatureForError (), name, missing);
return; return;
} }
@ -9461,7 +9494,7 @@ namespace Mono.CSharp
this.left = left; this.left = left;
this.spec = spec; this.spec = spec;
this.loc = spec.Location; this.loc = left.Location;
} }
public override TypeSpec ResolveAsType (IMemberContext ec) public override TypeSpec ResolveAsType (IMemberContext ec)
@ -9843,6 +9876,9 @@ namespace Mono.CSharp
// //
class CollectionElementInitializer : Invocation class CollectionElementInitializer : Invocation
{ {
public readonly bool IsSingle;
public class ElementInitializerArgument : Argument public class ElementInitializerArgument : Argument
{ {
public ElementInitializerArgument (Expression e) public ElementInitializerArgument (Expression e)
@ -9870,6 +9906,7 @@ namespace Mono.CSharp
public CollectionElementInitializer (Expression argument) public CollectionElementInitializer (Expression argument)
: base (null, new Arguments (1)) : base (null, new Arguments (1))
{ {
IsSingle = true;
base.arguments.Add (new ElementInitializerArgument (argument)); base.arguments.Add (new ElementInitializerArgument (argument));
this.loc = argument.Location; this.loc = argument.Location;
} }
@ -9877,6 +9914,7 @@ namespace Mono.CSharp
public CollectionElementInitializer (List<Expression> arguments, Location loc) public CollectionElementInitializer (List<Expression> arguments, Location loc)
: base (null, new Arguments (arguments.Count)) : base (null, new Arguments (arguments.Count))
{ {
IsSingle = false;
foreach (Expression e in arguments) foreach (Expression e in arguments)
base.arguments.Add (new ElementInitializerArgument (e)); base.arguments.Add (new ElementInitializerArgument (e));

5
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/field.cs

@ -640,13 +640,12 @@ namespace Mono.CSharp
} }
if (initializer != null) { if (initializer != null) {
Parent.RegisterFieldForInitialization (this, Parent.RegisterFieldForInitialization (this, new FieldInitializer (this, initializer, TypeExpression.Location));
new FieldInitializer (spec, initializer, this));
} }
if (declarators != null) { if (declarators != null) {
var t = new TypeExpression (MemberType, TypeExpression.Location);
foreach (var d in declarators) { foreach (var d in declarators) {
var t = new TypeExpression (MemberType, d.Name.Location);
var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes);
if (d.Initializer != null) if (d.Initializer != null)
f.initializer = d.Initializer; f.initializer = d.Initializer;

84
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/generic.cs

@ -737,6 +737,12 @@ namespace Mono.CSharp {
} }
} }
public bool HasAnyTypeConstraint {
get {
return (spec & (SpecialConstraint.Class | SpecialConstraint.Struct)) != 0 || ifaces != null || targs != null || HasTypeConstraint;
}
}
public bool HasTypeConstraint { public bool HasTypeConstraint {
get { get {
var bt = BaseType.BuiltinType; var bt = BaseType.BuiltinType;
@ -1226,6 +1232,30 @@ namespace Mono.CSharp {
return false; return false;
} }
public static bool HasAnyTypeParameterTypeConstrained (IGenericMethodDefinition md)
{
var tps = md.TypeParameters;
for (int i = 0; i < md.TypeParametersCount; ++i) {
if (tps[i].HasAnyTypeConstraint) {
return true;
}
}
return false;
}
public static bool HasAnyTypeParameterConstrained (IGenericMethodDefinition md)
{
var tps = md.TypeParameters;
for (int i = 0; i < md.TypeParametersCount; ++i) {
if (tps[i].IsConstrained) {
return true;
}
}
return false;
}
public override TypeSpec Mutate (TypeParameterMutator mutator) public override TypeSpec Mutate (TypeParameterMutator mutator)
{ {
return mutator.Mutate (this); return mutator.Mutate (this);
@ -1488,7 +1518,9 @@ namespace Mono.CSharp {
if (targs == null) if (targs == null)
throw new ArgumentNullException ("targs"); throw new ArgumentNullException ("targs");
// this.state = openType.state; this.state &= ~SharedStateFlags;
this.state |= (openType.state & SharedStateFlags);
this.context = context; this.context = context;
this.open_type = openType; this.open_type = openType;
this.targs = targs; this.targs = targs;
@ -2222,29 +2254,14 @@ namespace Mono.CSharp {
struct ConstraintChecker struct ConstraintChecker
{ {
IMemberContext mc; IMemberContext mc;
bool ignore_inferred_dynamic;
bool recursive_checks; bool recursive_checks;
public ConstraintChecker (IMemberContext ctx) public ConstraintChecker (IMemberContext ctx)
{ {
this.mc = ctx; this.mc = ctx;
ignore_inferred_dynamic = false;
recursive_checks = false; recursive_checks = false;
} }
#region Properties
public bool IgnoreInferredDynamic {
get {
return ignore_inferred_dynamic;
}
set {
ignore_inferred_dynamic = value;
}
}
#endregion
// //
// Checks the constraints of open generic type against type // Checks the constraints of open generic type against type
// arguments. This version is used for types which could not be // arguments. This version is used for types which could not be
@ -2289,14 +2306,11 @@ namespace Mono.CSharp {
// //
// Checks all type arguments againts type parameters constraints // Checks all type arguments againts type parameters constraints
// NOTE: It can run in probing mode when `mc' is null // NOTE: It can run in probing mode when `this.mc' is null
// //
public bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc) public bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc)
{ {
for (int i = 0; i < tparams.Length; i++) { for (int i = 0; i < tparams.Length; i++) {
if (ignore_inferred_dynamic && targs[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic)
continue;
var targ = targs[i]; var targ = targs[i];
if (!CheckConstraint (context, targ, tparams [i], loc)) if (!CheckConstraint (context, targ, tparams [i], loc))
return false; return false;
@ -2342,15 +2356,6 @@ namespace Mono.CSharp {
// Check the class constraint // Check the class constraint
// //
if (tparam.HasTypeConstraint) { if (tparam.HasTypeConstraint) {
var dep = tparam.BaseType.GetMissingDependencies ();
if (dep != null) {
if (mc == null)
return false;
ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
ok = false;
}
if (!CheckConversion (mc, context, atype, tparam, tparam.BaseType, loc)) { if (!CheckConversion (mc, context, atype, tparam, tparam.BaseType, loc)) {
if (mc == null) if (mc == null)
return false; return false;
@ -2364,19 +2369,6 @@ namespace Mono.CSharp {
// //
if (tparam.Interfaces != null) { if (tparam.Interfaces != null) {
foreach (TypeSpec iface in tparam.Interfaces) { foreach (TypeSpec iface in tparam.Interfaces) {
var dep = iface.GetMissingDependencies ();
if (dep != null) {
if (mc == null)
return false;
ImportedTypeDefinition.Error_MissingDependency (mc, dep, loc);
ok = false;
// return immediately to avoid duplicate errors because we are scanning
// expanded interface list
return false;
}
if (!CheckConversion (mc, context, atype, tparam, iface, loc)) { if (!CheckConversion (mc, context, atype, tparam, iface, loc)) {
if (mc == null) if (mc == null)
return false; return false;
@ -2466,14 +2458,6 @@ namespace Mono.CSharp {
return true; return true;
} }
//
// When partial/full type inference finds a dynamic type argument delay
// the constraint check to runtime, it can succeed for real underlying
// dynamic type
//
if (ignore_inferred_dynamic && HasDynamicTypeArgument (ttype.TypeArguments))
return true;
if (mc != null) { if (mc != null) {
mc.Module.Compiler.Report.SymbolRelatedToPreviousError (tparam); mc.Module.Compiler.Report.SymbolRelatedToPreviousError (tparam);
if (atype.IsGenericParameter) { if (atype.IsGenericParameter) {

49
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/import.cs

@ -90,7 +90,7 @@ namespace Mono.CSharp
if (cad.Count > 0) { if (cad.Count > 0) {
foreach (var ca in cad) { foreach (var ca in cad) {
var dt = ca.Constructor.DeclaringType; var dt = ca.Constructor.DeclaringType;
if (dt.Name != "DynamicAttribute" && dt.Namespace != CompilerServicesNamespace) if (dt.Name != "DynamicAttribute" || dt.Namespace != CompilerServicesNamespace)
continue; continue;
if (ca.ConstructorArguments.Count == 0) { if (ca.ConstructorArguments.Count == 0) {
@ -390,8 +390,10 @@ namespace Mono.CSharp
if ((mod & Modifiers.OVERRIDE) != 0) { if ((mod & Modifiers.OVERRIDE) != 0) {
bool is_real_override = false; bool is_real_override = false;
if (kind == MemberKind.Method && declaringType.BaseType != null) { if (kind == MemberKind.Method && declaringType.BaseType != null) {
var btype = declaringType.BaseType;
if (IsOverrideMethodBaseTypeAccessible (btype)) {
var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null); var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None); var candidate = MemberCache.FindMember (btype, filter, BindingRestriction.None);
// //
// For imported class method do additional validation to be sure that metadata // For imported class method do additional validation to be sure that metadata
@ -404,6 +406,7 @@ namespace Mono.CSharp
is_real_override = true; is_real_override = true;
} }
} }
}
if (!is_real_override) { if (!is_real_override) {
mod &= ~Modifiers.OVERRIDE; mod &= ~Modifiers.OVERRIDE;
@ -434,6 +437,30 @@ namespace Mono.CSharp
return ms; return ms;
} }
bool IsOverrideMethodBaseTypeAccessible (TypeSpec baseType)
{
switch (baseType.Modifiers & Modifiers.AccessibilityMask) {
case Modifiers.PUBLIC:
return true;
case Modifiers.INTERNAL:
//
// Check whether imported method in base type is accessible from compiled
// context
//
return baseType.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
case Modifiers.PRIVATE:
return false;
default:
// protected
// protected internal
//
// Method accessibility checks will be done later based on context
// where the method is called (CS0122 error will be reported for inaccessible)
//
return true;
}
}
// //
// Imports System.Reflection parameters // Imports System.Reflection parameters
// //
@ -835,6 +862,13 @@ namespace Mono.CSharp
import_cache.Add (type, spec); import_cache.Add (type, spec);
if (kind == MemberKind.TypeParameter) {
if (canImportBaseType)
ImportTypeParameterTypeConstraints ((TypeParameterSpec) spec, type);
return spec;
}
// //
// Two stage setup as the base type can be inflated declaring type or // Two stage setup as the base type can be inflated declaring type or
// another nested type inside same declaring type which has not been // another nested type inside same declaring type which has not been
@ -992,7 +1026,6 @@ namespace Mono.CSharp
ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ()); ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
} }
} }
} }
protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes) protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes)
@ -1796,7 +1829,15 @@ namespace Mono.CSharp
// or referenced from the user core in which case compilation error has to // or referenced from the user core in which case compilation error has to
// be reported because compiler cannot continue anyway // be reported because compiler cannot continue anyway
// //
foreach (var t in types) { for (int i = 0; i < types.Count; ++i) {
var t = types [i];
//
// Report missing types only once per type
//
if (i > 0 && types.IndexOf (t) < i)
continue;
string name = t.GetSignatureForError (); string name = t.GetSignatureForError ();
if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) { if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {

4
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/iterators.cs

@ -972,7 +972,9 @@ namespace Mono.CSharp
method.Block.IsCompilerGenerated = true; method.Block.IsCompilerGenerated = true;
method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block)); method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
storey.AddMember (method); // Cannot it add to storey because it'd be emitted before nested
// anonoymous methods which could capture shared variable
return method; return method;
} }

50
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/location.cs

@ -52,13 +52,15 @@ namespace Mono.CSharp
} }
} }
static readonly byte[] MD5Algorith = { 96, 166, 110, 64, 207, 100, 130, 76, 182, 240, 66, 212, 129, 114, 167, 153 };
public readonly string Name; public readonly string Name;
public readonly string FullPathName; public readonly string FullPathName;
public readonly int Index; public readonly int Index;
public bool AutoGenerated; public bool AutoGenerated;
SourceFileEntry file; SourceFileEntry file;
byte[] guid, checksum; byte[] algGuid, checksum;
List<LocationRegion> hidden_lines; List<LocationRegion> hidden_lines;
public SourceFile (string name, string path, int index) public SourceFile (string name, string path, int index)
@ -68,15 +70,32 @@ namespace Mono.CSharp
this.FullPathName = path; this.FullPathName = path;
} }
public byte[] Checksum {
get {
return checksum;
}
}
public bool HasChecksum {
get {
return checksum != null;
}
}
public SourceFileEntry SourceFileEntry { public SourceFileEntry SourceFileEntry {
get { get {
return file; return file;
} }
} }
public void SetChecksum (byte[] guid, byte[] checksum) public void SetChecksum (byte[] checksum)
{ {
this.guid = guid; SetChecksum (MD5Algorith, checksum);
}
public void SetChecksum (byte[] algorithmGuid, byte[] checksum)
{
this.algGuid = algorithmGuid;
this.checksum = checksum; this.checksum = checksum;
} }
@ -85,13 +104,9 @@ namespace Mono.CSharp
if (hidden_lines != null) if (hidden_lines != null)
hidden_lines.Sort (); hidden_lines.Sort ();
if (guid != null) { file = new SourceFileEntry (symwriter, FullPathName, algGuid, checksum);
file = new SourceFileEntry (symwriter, FullPathName, guid, checksum);
} else {
file = new SourceFileEntry (symwriter, FullPathName);
if (AutoGenerated) if (AutoGenerated)
file.SetAutoGenerated (); file.SetAutoGenerated ();
}
return file; return file;
} }
@ -177,7 +192,6 @@ namespace Mono.CSharp
const int max_column = column_mask; const int max_column = column_mask;
static List<SourceFile> source_list; static List<SourceFile> source_list;
static int current_source;
static Checkpoint [] checkpoints; static Checkpoint [] checkpoints;
static int checkpoint_index; static int checkpoint_index;
@ -192,7 +206,6 @@ namespace Mono.CSharp
public static void Reset () public static void Reset ()
{ {
source_list = new List<SourceFile> (); source_list = new List<SourceFile> ();
current_source = 0;
checkpoint_index = 0; checkpoint_index = 0;
} }
@ -220,13 +233,7 @@ namespace Mono.CSharp
checkpoints [0] = new Checkpoint (0, 0); checkpoints [0] = new Checkpoint (0, 0);
} }
static public void Push (SourceFile file) public Location (SourceFile file, int row, int column)
{
current_source = file != null ? file.Index : -1;
// File is always pushed before being changed.
}
public Location (int row, int column)
{ {
if (row <= 0) if (row <= 0)
token = 0; token = 0;
@ -237,6 +244,9 @@ namespace Mono.CSharp
long target = -1; long target = -1;
long delta = 0; long delta = 0;
// TODO: For eval only, need better handling of empty
int file_index = file == null ? 0 : file.Index;
// FIXME: This value is certainly wrong but what was the intension // FIXME: This value is certainly wrong but what was the intension
int max = checkpoint_index < 10 ? int max = checkpoint_index < 10 ?
checkpoint_index : 10; checkpoint_index : 10;
@ -245,13 +255,13 @@ namespace Mono.CSharp
delta = row - offset; delta = row - offset;
if (delta >= 0 && if (delta >= 0 &&
delta < (1 << line_delta_bits) && delta < (1 << line_delta_bits) &&
checkpoints [checkpoint_index - i].File == current_source) { checkpoints[checkpoint_index - i].File == file_index) {
target = checkpoint_index - i; target = checkpoint_index - i;
break; break;
} }
} }
if (target == -1) { if (target == -1) {
AddCheckpoint (current_source, row); AddCheckpoint (file_index, row);
target = checkpoint_index; target = checkpoint_index;
delta = row % (1 << line_delta_bits); delta = row % (1 << line_delta_bits);
} }
@ -269,7 +279,7 @@ namespace Mono.CSharp
public static Location operator - (Location loc, int columns) public static Location operator - (Location loc, int columns)
{ {
return new Location (loc.Row, loc.Column - columns); return new Location (loc.SourceFile, loc.Row, loc.Column - columns);
} }
static void AddCheckpoint (int file, int row) static void AddCheckpoint (int file, int row)

7
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/membercache.cs

@ -435,12 +435,15 @@ namespace Mono.CSharp {
// A special method to work with member lookup only. It returns a list of all members named @name // A special method to work with member lookup only. It returns a list of all members named @name
// starting from @container. It's very performance sensitive // starting from @container. It's very performance sensitive
// //
public static IList<MemberSpec> FindMembers (TypeSpec container, string name, bool declaredOnly) // declaredOnlyClass cannot be used interfaces. Manual filtering is required because names are
// compacted
//
public static IList<MemberSpec> FindMembers (TypeSpec container, string name, bool declaredOnlyClass)
{ {
IList<MemberSpec> applicable; IList<MemberSpec> applicable;
do { do {
if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnly) if (container.MemberCache.member_hash.TryGetValue (name, out applicable) || declaredOnlyClass)
return applicable; return applicable;
container = container.BaseType; container = container.BaseType;

58
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs

@ -496,6 +496,20 @@ namespace Mono.CSharp {
missing.AddRange (m); missing.AddRange (m);
} }
if (Arity > 0) {
foreach (var tp in GenericDefinition.TypeParameters) {
var m = tp.GetMissingDependencies ();
if (m == null)
continue;
if (missing == null)
missing = new List<TypeSpec> ();
missing.AddRange (m);
}
}
return missing; return missing;
} }
@ -1199,6 +1213,9 @@ namespace Mono.CSharp {
block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location); block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, Location);
ModFlags |= Modifiers.DEBUGGER_HIDDEN; ModFlags |= Modifiers.DEBUGGER_HIDDEN;
} }
if (Compiler.Settings.WriteMetadataOnly)
block = null;
} }
if ((ModFlags & Modifiers.STATIC) == 0) if ((ModFlags & Modifiers.STATIC) == 0)
@ -1287,10 +1304,18 @@ namespace Mono.CSharp {
} }
} }
base.Emit (); if (block != null && block.StateMachine != null) {
var psm = block.StateMachine is IteratorStorey ?
Module.PredefinedAttributes.IteratorStateMachine :
Module.PredefinedAttributes.AsyncStateMachine;
psm.EmitAttribute (MethodBuilder, block.StateMachine);
}
if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0) if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder); Module.PredefinedAttributes.Extension.EmitAttribute (MethodBuilder);
base.Emit ();
} catch { } catch {
Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}", Console.WriteLine ("Internal compiler error at {0}: exception caught while emitting {1}",
Location, MethodBuilder); Location, MethodBuilder);
@ -1418,8 +1443,7 @@ namespace Mono.CSharp {
base_ctor = ConstructorLookup (ec, type, ref argument_list, loc); base_ctor = ConstructorLookup (ec, type, ref argument_list, loc);
} }
// TODO MemberCache: Does it work for inflated types ? if (base_ctor != null && base_ctor.MemberDefinition == caller_builder.Spec.MemberDefinition) {
if (base_ctor == caller_builder.Spec){
ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself",
caller_builder.GetSignatureForError ()); caller_builder.GetSignatureForError ());
} }
@ -1604,12 +1628,17 @@ namespace Mono.CSharp {
Parent.MemberCache.AddMember (spec); Parent.MemberCache.AddMember (spec);
if (block != null) {
// It's here only to report an error // It's here only to report an error
if (block != null && block.IsIterator) { if (block.IsIterator) {
member_type = Compiler.BuiltinTypes.Void; member_type = Compiler.BuiltinTypes.Void;
Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags); Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
} }
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
return true; return true;
} }
@ -1643,6 +1672,7 @@ namespace Mono.CSharp {
BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void); BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void);
bc.Set (ResolveContext.Options.ConstructorScope); bc.Set (ResolveContext.Options.ConstructorScope);
if (block != null) {
// //
// If we use a "this (...)" constructor initializer, then // If we use a "this (...)" constructor initializer, then
// do not emit field initializers, they are initialized in the other constructor // do not emit field initializers, they are initialized in the other constructor
@ -1650,7 +1680,6 @@ namespace Mono.CSharp {
if (!(Initializer is ConstructorThisInitializer)) if (!(Initializer is ConstructorThisInitializer))
Parent.PartialContainer.ResolveFieldInitializers (bc); Parent.PartialContainer.ResolveFieldInitializers (bc);
if (block != null) {
if (!IsStatic) { if (!IsStatic) {
if (Initializer == null) { if (Initializer == null) {
if (Parent.PartialContainer.Kind == MemberKind.Struct) { if (Parent.PartialContainer.Kind == MemberKind.Struct) {
@ -1951,7 +1980,7 @@ namespace Mono.CSharp {
// //
if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) { if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
implementing = null; implementing = null;
} else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) { } else if (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) {
// //
// We are not implementing interface when base class already implemented it // We are not implementing interface when base class already implemented it
// //
@ -2142,6 +2171,16 @@ namespace Mono.CSharp {
return true; return true;
} }
public override bool Define ()
{
base.Define ();
if (Compiler.Settings.WriteMetadataOnly)
block = null;
return true;
}
public override void Emit() public override void Emit()
{ {
var base_type = Parent.PartialContainer.BaseType; var base_type = Parent.PartialContainer.BaseType;
@ -2505,7 +2544,8 @@ namespace Mono.CSharp {
if (!base.Define ()) if (!base.Define ())
return false; return false;
if (block != null && block.IsIterator) { if (block != null) {
if (block.IsIterator) {
// //
// Current method is turned into automatically generated // Current method is turned into automatically generated
// wrapper which creates an instance of iterator // wrapper which creates an instance of iterator
@ -2514,6 +2554,10 @@ namespace Mono.CSharp {
ModFlags |= Modifiers.DEBUGGER_HIDDEN; ModFlags |= Modifiers.DEBUGGER_HIDDEN;
} }
if (Compiler.Settings.WriteMetadataOnly)
block = null;
}
// imlicit and explicit operator of same types are not allowed // imlicit and explicit operator of same types are not allowed
if (OperatorType == OpType.Explicit) if (OperatorType == OpType.Explicit)
Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters); Parent.MemberCache.CheckExistingMembersOverloads (this, GetMetadataName (OpType.Implicit), parameters);

2
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/module.cs

@ -429,7 +429,7 @@ namespace Mono.CSharp
base.EmitContainer (); base.EmitContainer ();
if (Compiler.Report.Errors == 0) if (Compiler.Report.Errors == 0 && !Compiler.Settings.WriteMetadataOnly)
VerifyMembers (); VerifyMembers ();
if (anonymous_types != null) { if (anonymous_types != null) {

161
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/namespace.cs

@ -41,6 +41,46 @@ namespace Mono.CSharp {
report.Error (1681, loc, "The global extern alias cannot be redefined"); report.Error (1681, loc, "The global extern alias cannot be redefined");
} }
//
// For better error reporting where we try to guess missing using directive
//
public List<string> FindTypeNamespaces (IMemberContext ctx, string name, int arity)
{
List<string> res = null;
foreach (var ns in all_namespaces) {
var type = ns.Value.LookupType (ctx, name, arity, LookupMode.Normal, Location.Null);
if (type != null) {
if (res == null)
res = new List<string> ();
res.Add (ns.Key);
}
}
return res;
}
//
// For better error reporting where compiler tries to guess missing using directive
//
public List<string> FindExtensionMethodNamespaces (IMemberContext ctx, TypeSpec extensionType, string name, int arity)
{
List<string> res = null;
foreach (var ns in all_namespaces) {
var methods = ns.Value.LookupExtensionMethod (ctx, extensionType, name, arity);
if (methods != null) {
if (res == null)
res = new List<string> ();
res.Add (ns.Key);
}
}
return res;
}
public void RegisterNamespace (Namespace child) public void RegisterNamespace (Namespace child)
{ {
if (child != this) if (child != this)
@ -181,14 +221,51 @@ namespace Mono.CSharp {
return; return;
} }
string assembly = null;
string possible_name = fullname + "." + name;
// Only assembly unique name should be added
switch (possible_name) {
case "System.Drawing":
case "System.Web.Services":
case "System.Web":
case "System.Data":
case "System.Configuration":
case "System.Data.Services":
case "System.DirectoryServices":
case "System.Json":
case "System.Net.Http":
case "System.Numerics":
case "System.Runtime.Caching":
case "System.ServiceModel":
case "System.Transactions":
case "System.Web.Routing":
case "System.Xml.Linq":
case "System.Xml":
assembly = possible_name;
break;
case "System.Linq":
case "System.Linq.Expressions":
assembly = "System.Core";
break;
case "System.Windows.Forms":
case "System.Windows.Forms.Layout":
assembly = "System.Windows.Name";
break;
}
assembly = assembly == null ? "an" : "`" + assembly + "'";
if (this is GlobalRootNamespace) { if (this is GlobalRootNamespace) {
ctx.Module.Compiler.Report.Error (400, loc, ctx.Module.Compiler.Report.Error (400, loc,
"The type or namespace name `{0}' could not be found in the global namespace (are you missing an assembly reference?)", "The type or namespace name `{0}' could not be found in the global namespace. Are you missing {1} assembly reference?",
name); name, assembly);
} else { } else {
ctx.Module.Compiler.Report.Error (234, loc, ctx.Module.Compiler.Report.Error (234, loc,
"The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing an assembly reference?", "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are you missing {2} assembly reference?",
name, GetSignatureForError ()); name, GetSignatureForError (), assembly);
} }
} }
@ -209,10 +286,16 @@ namespace Mono.CSharp {
ns_parent = this; ns_parent = this;
} }
return ns_parent.TryAddNamespace (name.Basename);
}
Namespace TryAddNamespace (string name)
{
Namespace ns; Namespace ns;
if (!ns_parent.namespaces.TryGetValue (name.Basename, out ns)) {
ns = new Namespace (ns_parent, name.Basename); if (!namespaces.TryGetValue (name, out ns)) {
ns_parent.namespaces.Add (name.Basename, ns); ns = new Namespace (this, name);
namespaces.Add (name, ns);
} }
return ns; return ns;
@ -591,6 +674,14 @@ namespace Mono.CSharp {
} }
} }
public IEnumerable<string> Conditionals {
get {
if (conditionals == null)
return Enumerable.Empty<string> ();
return conditionals.Where (kv => kv.Value).Select (kv => kv.Key);
}
}
public string FileName { public string FileName {
get { get {
return file.Name; return file.Name;
@ -801,8 +892,10 @@ namespace Mono.CSharp {
name = mn.Name; name = mn.Name;
} }
var names_container = Parent == null ? Module : (TypeContainer) this;
MemberCore mc; MemberCore mc;
if (defined_names.TryGetValue (name, out mc)) { if (names_container.DefinedNames.TryGetValue (name, out mc)) {
if (tc is NamespaceContainer && mc is NamespaceContainer) { if (tc is NamespaceContainer && mc is NamespaceContainer) {
containers.Add (tc); containers.Add (tc);
return; return;
@ -816,7 +909,7 @@ namespace Mono.CSharp {
GetSignatureForError (), mn.GetSignatureForError ()); GetSignatureForError (), mn.GetSignatureForError ());
} }
} else { } else {
defined_names.Add (name, tc); names_container.DefinedNames.Add (name, tc);
} }
base.AddTypeContainer (tc); base.AddTypeContainer (tc);
@ -1100,44 +1193,6 @@ namespace Mono.CSharp {
return match; return match;
} }
static void MsgtryRef (string s)
{
Console.WriteLine (" Try using -r:" + s);
}
static void MsgtryPkg (string s)
{
Console.WriteLine (" Try using -pkg:" + s);
}
public static void Error_NamespaceNotFound (Location loc, string name, Report Report)
{
Report.Error (246, loc, "The type or namespace name `{0}' could not be found. Are you missing a using directive or an assembly reference?",
name);
switch (name) {
case "Gtk": case "GtkSharp":
MsgtryPkg ("gtk-sharp-2.0");
break;
case "Gdk": case "GdkSharp":
MsgtryPkg ("gdk-sharp-2.0");
break;
case "Glade": case "GladeSharp":
MsgtryPkg ("glade-sharp-2.0");
break;
case "System.Drawing":
case "System.Web.Services":
case "System.Web":
case "System.Data":
case "System.Windows.Forms":
MsgtryRef (name);
break;
}
}
protected override void DefineNamespace () protected override void DefineNamespace ()
{ {
if (namespace_using_table == null) if (namespace_using_table == null)
@ -1180,11 +1235,23 @@ namespace Mono.CSharp {
entry.Define (this); entry.Define (this);
//
// It's needed for repl only, when using clause cannot be resolved don't hold it in
// global list which is resolved for each evaluation
//
if (entry.ResolvedExpression == null) {
clauses.RemoveAt (i--);
continue;
}
Namespace using_ns = entry.ResolvedExpression as Namespace; Namespace using_ns = entry.ResolvedExpression as Namespace;
if (using_ns == null) if (using_ns == null)
continue; continue;
if (list.Contains (using_ns)) { if (list.Contains (using_ns)) {
// Ensure we don't report the warning multiple times in repl
clauses.RemoveAt (i--);
Compiler.Report.Warning (105, 3, entry.Location, Compiler.Report.Warning (105, 3, entry.Location,
"The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ()); "The using directive for `{0}' appeared previously in this namespace", using_ns.GetSignatureForError ());
} else { } else {

10
NRefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/nullable.cs

@ -539,8 +539,8 @@ namespace Mono.CSharp.Nullable
Expression user_operator; Expression user_operator;
MethodSpec wrap_ctor; MethodSpec wrap_ctor;
public LiftedBinaryOperator (Binary.Operator op, Expression left, Expression right, Location loc) public LiftedBinaryOperator (Binary.Operator op, Expression left, Expression right)
: base (op, left, right, loc) : base (op, left, right)
{ {
} }
@ -583,7 +583,7 @@ namespace Mono.CSharp.Nullable
Constant c = new BoolConstant (ec.BuiltinTypes, Oper == Operator.Inequality, loc); Constant c = new BoolConstant (ec.BuiltinTypes, Oper == Operator.Inequality, loc);
if ((Oper & Operator.EqualityMask) != 0) { if ((Oper & Operator.EqualityMask) != 0) {
ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is `{1}'", ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is always `{1}'",
TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ()); TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ());
} else { } else {
ec.Report.Warning (464, 2, loc, "The result of comparing type `{0}' with null is always `{1}'", ec.Report.Warning (464, 2, loc, "The result of comparing type `{0}' with null is always `{1}'",
@ -1001,11 +1001,11 @@ namespace Mono.CSharp.Nullable
Expression left, right; Expression left, right;
Unwrap unwrap; Unwrap unwrap;
public NullCoalescingOperator (Expression left, Expression right, Location loc) public NullCoalescingOperator (Expression left, Expression right)
{ {
this.left = left; this.left = left;
this.right = right; this.right = right;
this.loc = loc; this.loc = left.Location;
} }
public Expression LeftExpression { public Expression LeftExpression {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save