From 20dce7a122ec78619b5452040e4f7c540d78d037 Mon Sep 17 00:00:00 2001 From: mkrueger Date: Thu, 20 May 2021 13:34:54 +0200 Subject: Ported evaluator to roslyn. --- .../LambdaBodyOutputVisitor.cs | 652 ++---------- .../NRefactoryExpressionEvaluator.cs | 24 +- .../NRefactoryExpressionEvaluatorVisitor.cs | 1083 ++++++-------------- .../NRefactoryExpressionResolverVisitor.cs | 58 +- .../NRefactoryExtensions.cs | 137 +-- Mono.Debugging/Mono.Debugging.csproj | 6 +- 6 files changed, 474 insertions(+), 1486 deletions(-) diff --git a/Mono.Debugging/Mono.Debugging.Evaluation/LambdaBodyOutputVisitor.cs b/Mono.Debugging/Mono.Debugging.Evaluation/LambdaBodyOutputVisitor.cs index d71eb8a..527416c 100644 --- a/Mono.Debugging/Mono.Debugging.Evaluation/LambdaBodyOutputVisitor.cs +++ b/Mono.Debugging/Mono.Debugging.Evaluation/LambdaBodyOutputVisitor.cs @@ -2,11 +2,11 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; - +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Mono.Debugging.Client; -using ICSharpCode.NRefactory.CSharp; - namespace Mono.Debugging.Evaluation { // Outputs lambda expression inputted on Immediate Pad. Also @@ -16,7 +16,7 @@ namespace Mono.Debugging.Evaluation // identifer. // - Collect variable references for outside the lambda // (local variables/properties...) - public class LambdaBodyOutputVisitor : CSharpOutputVisitor + public class LambdaBodyOutputVisitor : CSharpSyntaxWalker { readonly Dictionary userVariables; readonly EvaluationContext ctx; @@ -25,7 +25,7 @@ namespace Mono.Debugging.Evaluation List definedIdentifier; int gensymCount; - public LambdaBodyOutputVisitor (EvaluationContext ctx, Dictionary userVariables, TextWriter writer) : base (writer, FormattingOptionsFactory.CreateMono ()) + public LambdaBodyOutputVisitor (EvaluationContext ctx, Dictionary userVariables, TextWriter writer) { this.ctx = ctx; this.userVariables = userVariables; @@ -33,12 +33,21 @@ namespace Mono.Debugging.Evaluation this.definedIdentifier = new List (); } + void WriteKeyword (string keyword) + { + + } + void WriteIdentifier (string keyword) + { + + } + public Tuple[] GetLocalValues () { var locals = new Tuple[localValues.Count]; int n = 0; - foreach(var localv in localValues.Values) { - locals [n] = localv; + foreach (var localv in localValues.Values) { + locals[n] = localv; n++; } return locals; @@ -54,7 +63,7 @@ namespace Mono.Debugging.Evaluation return new NotSupportedExpressionException (); } - static Exception EvaluationError (string message, params object [] args) + static Exception EvaluationError (string message, params object[] args) { return new EvaluatorException (message, args); } @@ -87,22 +96,22 @@ namespace Mono.Debugging.Evaluation } } - ValueReference Evaluate (IdentifierExpression t) + ValueReference Evaluate (IdentifierNameSyntax t) { - var visitor = new NRefactoryExpressionEvaluatorVisitor (ctx, t.Identifier, null, userVariables); - return t.AcceptVisitor (visitor); + var visitor = new NRefactoryExpressionEvaluatorVisitor (ctx, t.Identifier.ValueText, null, userVariables); + return visitor.Visit (t); } - ValueReference Evaluate (BaseReferenceExpression t) + ValueReference Evaluate (BaseExpressionSyntax t) { var visitor = new NRefactoryExpressionEvaluatorVisitor (ctx, "base", null, userVariables); - return t.AcceptVisitor (visitor); + return visitor.Visit (t); } - ValueReference Evaluate (ThisReferenceExpression t) + ValueReference Evaluate (ThisExpressionSyntax t) { var visitor = new NRefactoryExpressionEvaluatorVisitor (ctx, "this", null, userVariables); - return t.AcceptVisitor (visitor); + return visitor.Visit (t); } string GenerateSymbol (string s) @@ -141,14 +150,14 @@ namespace Mono.Debugging.Evaluation string GetLocalName (string name) { Tuple pair; - if (localValues.TryGetValue(name, out pair)) + if (localValues.TryGetValue (name, out pair)) return pair.Item1; return null; } bool ExistsLocalName (string localName) { - foreach(var pair in localValues.Values) { + foreach (var pair in localValues.Values) { if (pair.Item1 == localName) return true; } @@ -157,79 +166,25 @@ namespace Mono.Debugging.Evaluation #region IAstVisitor implementation - public override void VisitAnonymousMethodExpression (AnonymousMethodExpression anonymousMethodExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitUndocumentedExpression (UndocumentedExpression undocumentedExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitArrayCreateExpression (ArrayCreateExpression arrayCreateExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitAsExpression (AsExpression asExpression) - { - } - */ - public override void VisitAssignmentExpression (AssignmentExpression assignmentExpression) + public override void VisitAssignmentExpression (AssignmentExpressionSyntax node) { throw EvaluationError ("Not support assignment expression inside lambda"); } - public override void VisitBaseReferenceExpression (BaseReferenceExpression baseReferenceExpression) + public override void VisitBaseExpression (BaseExpressionSyntax node) { - StartNode (baseReferenceExpression); var basee = "base"; - var localbase = GetLocalName(basee); + var localbase = GetLocalName (basee); if (localbase == null) { - var vr = Evaluate (baseReferenceExpression); + var vr = Evaluate (node); localbase = AddToLocals (basee, vr, true); } WriteKeyword (localbase); - EndNode (baseReferenceExpression); - } - /* - public override void VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression) - { - } - *//* - public override void VisitCastExpression (CastExpression castExpression) - { - } - */ - public override void VisitCheckedExpression (CheckedExpression checkedExpression) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitConditionalExpression (ConditionalExpression conditionalExpression) - { - } - */ - public override void VisitDefaultValueExpression (DefaultValueExpression defaultValueExpression) - { - throw NotSupportedToConsistency (); } - public override void VisitDirectionExpression (DirectionExpression directionExpression) + public override void VisitIdentifierName (IdentifierNameSyntax node) { - throw NotSupportedToConsistency (); - } - - public override void VisitIdentifierExpression (IdentifierExpression identifierExpression) - { - StartNode (identifierExpression); - var identifier = identifierExpression.Identifier; + var identifier = node.Identifier.ValueText; var localIdentifier = ""; if (definedIdentifier.Contains (identifier)) { @@ -237,32 +192,31 @@ namespace Mono.Debugging.Evaluation } else { localIdentifier = GetLocalName (identifier); if (localIdentifier == null) { - var vr = Evaluate (identifierExpression); + var vr = Evaluate (node); localIdentifier = AddToLocals (identifier, vr); } } - var idToken = identifierExpression.IdentifierToken; - idToken.Name = localIdentifier; - WriteIdentifier (idToken); - WriteTypeArguments (identifierExpression.TypeArguments); - EndNode (identifierExpression); + WriteIdentifier (node.Identifier.ValueText); } - /* - public override void VisitIndexerExpression (IndexerExpression indexerExpression) + + public override void VisitGenericName (GenericNameSyntax node) { + WriteIdentifier (node.Identifier.ValueText); + foreach (var arg in node.TypeArgumentList.Arguments) { + Visit (arg); + } } - */ - public override void VisitInvocationExpression (InvocationExpression invocationExpression) + + public override void VisitInvocationExpression (InvocationExpressionSyntax node) { - var invocationTarget = invocationExpression.Target; - if (!(invocationTarget is IdentifierExpression)) { - base.VisitInvocationExpression (invocationExpression); + var invocationTarget = node.Expression; + if (!(invocationTarget is IdentifierNameSyntax method)) { + base.VisitInvocationExpression (node); return; } - var argc = invocationExpression.Arguments.Count; - var method = (IdentifierExpression)invocationTarget; - var methodName = method.Identifier; + var argc = node.ArgumentList.Arguments.Count; + var methodName = method.Identifier.ValueText; var vref = ctx.Adapter.GetThisReference (ctx); var vtype = ctx.Adapter.GetEnclosingType (ctx); string accessor = null; @@ -296,527 +250,51 @@ namespace Mono.Debugging.Evaluation } } - StartNode (invocationExpression); if (accessor == null) - WriteIdentifier (method.Identifier); + WriteIdentifier (methodName); else WriteKeyword (accessor + "." + methodName); - Space (policy.SpaceBeforeMethodCallParentheses); - WriteCommaSeparatedListInParenthesis (invocationExpression.Arguments, policy.SpaceWithinMethodCallParentheses); - EndNode (invocationExpression); - } - - /* - public override void VisitIsExpression (IsExpression isExpression) - { - }*/ - - public override void VisitLambdaExpression (LambdaExpression lambdaExpression) - { - foreach (var par in lambdaExpression.Parameters) { - if (par.ParameterModifier != ICSharpCode.NRefactory.CSharp.ParameterModifier.None) - throw NotSupported(); - - definedIdentifier.Add(par.Name); + WriteIdentifier ("("); + for (int i = 0; i < node.ArgumentList.Arguments.Count; i++) { + if (i > 0) + WriteIdentifier (", "); + Visit (node.ArgumentList.Arguments[i]); } - - base.VisitLambdaExpression (lambdaExpression); + WriteIdentifier (")"); } - /* - public override void VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression) - { - }*/ - public override void VisitNamedArgumentExpression (NamedArgumentExpression namedArgumentExpression) + public override void VisitSimpleLambdaExpression (SimpleLambdaExpressionSyntax node) { - throw NotSupportedToConsistency (); - } + if (node.Parameter.Modifiers.Count > 0) + throw NotSupported (); - public override void VisitNamedExpression (NamedExpression namedExpression) - { - throw NotSupportedToConsistency (); + definedIdentifier.Add (node.Parameter.Identifier.ValueText); + Visit (node.Body); } - /* - public override void VisitNullReferenceExpression (NullReferenceExpression nullReferenceExpression) - { - } - *//* - public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression) - { - }*/ - public override void VisitAnonymousTypeCreateExpression (AnonymousTypeCreateExpression anonymousTypeCreateExpression) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitParenthesizedExpression (ParenthesizedExpression parenthesizedExpression) + public override void VisitThisExpression (ThisExpressionSyntax node) { - }*/ - - public override void VisitPointerReferenceExpression (PointerReferenceExpression pointerReferenceExpression) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitPrimitiveExpression (PrimitiveExpression primitiveExpression) - { - return primitiveExpression.ToString (); - }*/ - - public override void VisitSizeOfExpression (SizeOfExpression sizeOfExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitStackAllocExpression (StackAllocExpression stackAllocExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitThisReferenceExpression (ThisReferenceExpression thisReferenceExpression) - { - StartNode (thisReferenceExpression); var thiss = "this"; var localthis = GetLocalName (thiss); if (localthis == null) { - var vr = Evaluate (thisReferenceExpression); + var vr = Evaluate (node); localthis = AddToLocals (thiss, vr, true); } WriteKeyword (localthis); - EndNode (thisReferenceExpression); - } - /* - public override void VisitTypeOfExpression (TypeOfExpression typeOfExpression) - { - }*/ - /* - public override void VisitTypeReferenceExpression (TypeReferenceExpression typeReferenceExpression) - { - }*//* - public override void VisitUnaryOperatorExpression (UnaryOperatorExpression unaryOperatorExpression) - { - }*/ - - public override void VisitUncheckedExpression (UncheckedExpression uncheckedExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryExpression (QueryExpression queryExpression) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryContinuationClause (QueryContinuationClause queryContinuationClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryFromClause (QueryFromClause queryFromClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryLetClause (QueryLetClause queryLetClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryWhereClause (QueryWhereClause queryWhereClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryJoinClause (QueryJoinClause queryJoinClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryOrderClause (QueryOrderClause queryOrderClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryOrdering (QueryOrdering queryOrdering) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQuerySelectClause (QuerySelectClause querySelectClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitQueryGroupClause (QueryGroupClause queryGroupClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitAttribute (ICSharpCode.NRefactory.CSharp.Attribute attribute) - { - throw NotSupportedToConsistency (); - } - - public override void VisitAttributeSection (AttributeSection attributeSection) - { - throw NotSupportedToConsistency (); - } - - public override void VisitDelegateDeclaration (DelegateDeclaration delegateDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitNamespaceDeclaration (NamespaceDeclaration namespaceDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitTypeDeclaration (TypeDeclaration typeDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitUsingAliasDeclaration (UsingAliasDeclaration usingAliasDeclaration) - { - throw NotSupportedToConsistency (); } - public override void VisitUsingDeclaration (UsingDeclaration usingDeclaration) + public override void VisitParameter (ParameterSyntax node) { - throw NotSupportedToConsistency (); - } - - public override void VisitExternAliasDeclaration (ExternAliasDeclaration externAliasDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitBlockStatement (BlockStatement blockStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitBreakStatement (BreakStatement breakStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitCheckedStatement (CheckedStatement checkedStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitContinueStatement (ContinueStatement continueStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitDoWhileStatement (DoWhileStatement doWhileStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitEmptyStatement (EmptyStatement emptyStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitExpressionStatement (ExpressionStatement expressionStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitFixedStatement (FixedStatement fixedStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitForeachStatement (ForeachStatement foreachStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitForStatement (ForStatement forStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitGotoCaseStatement (GotoCaseStatement gotoCaseStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitGotoDefaultStatement (GotoDefaultStatement gotoDefaultStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitGotoStatement (GotoStatement gotoStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitIfElseStatement (IfElseStatement ifElseStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitLabelStatement (LabelStatement labelStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitLockStatement (LockStatement lockStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitReturnStatement (ReturnStatement returnStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitSwitchStatement (SwitchStatement switchStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitSwitchSection (SwitchSection switchSection) - { - throw NotSupportedToConsistency (); - } - - public override void VisitCaseLabel (CaseLabel caseLabel) - { - throw NotSupportedToConsistency (); - } - - public override void VisitThrowStatement (ThrowStatement throwStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitTryCatchStatement (TryCatchStatement tryCatchStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitCatchClause (CatchClause catchClause) - { - throw NotSupportedToConsistency (); - } - - public override void VisitUncheckedStatement (UncheckedStatement uncheckedStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitUnsafeStatement (UnsafeStatement unsafeStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitUsingStatement (UsingStatement usingStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitVariableDeclarationStatement (VariableDeclarationStatement variableDeclarationStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitWhileStatement (WhileStatement whileStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitYieldBreakStatement (YieldBreakStatement yieldBreakStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitYieldReturnStatement (YieldReturnStatement yieldReturnStatement) - { - throw NotSupportedToConsistency (); - } - - public override void VisitAccessor (Accessor accessor) - { - throw NotSupportedToConsistency (); - } - - public override void VisitConstructorDeclaration (ConstructorDeclaration constructorDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitConstructorInitializer (ConstructorInitializer constructorInitializer) - { - throw NotSupportedToConsistency (); - } - - public override void VisitDestructorDeclaration (DestructorDeclaration destructorDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitEnumMemberDeclaration (EnumMemberDeclaration enumMemberDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitEventDeclaration (EventDeclaration eventDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitCustomEventDeclaration (CustomEventDeclaration customEventDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitFieldDeclaration (FieldDeclaration fieldDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitIndexerDeclaration (IndexerDeclaration indexerDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitMethodDeclaration (MethodDeclaration methodDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitOperatorDeclaration (OperatorDeclaration operatorDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitParameterDeclaration (ParameterDeclaration parameterDeclaration) - { - if (parameterDeclaration.Parent is LambdaExpression) - base.VisitParameterDeclaration (parameterDeclaration); + if (node.Parent is SimpleNameSyntax) + base.VisitParameter (node); else throw NotSupportedToConsistency (); } - public override void VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitVariableInitializer (VariableInitializer variableInitializer) - { - throw NotSupportedToConsistency (); - } - - public override void VisitFixedFieldDeclaration (FixedFieldDeclaration fixedFieldDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitFixedVariableInitializer (FixedVariableInitializer fixedVariableInitializer) - { - throw NotSupportedToConsistency (); - } - - public override void VisitSyntaxTree (SyntaxTree syntaxTree) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitSimpleType (SimpleType simpleType) - { - }*/ - /* - public override void VisitMemberType (MemberType memberType) - { - }*/ - /* - public override void VisitComposedType (ComposedType composedType) - { - }*/ - - public override void VisitArraySpecifier (ArraySpecifier arraySpecifier) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitPrimitiveType (PrimitiveType primitiveType) - { - }*/ - - public override void VisitComment (Comment comment) - { - throw NotSupportedToConsistency (); - } - - public override void VisitWhitespace (WhitespaceNode whitespaceNode) + public override void DefaultVisit (SyntaxNode node) { throw NotSupportedToConsistency (); } - - public override void VisitText (TextNode textNode) - { - throw NotSupportedToConsistency (); - } - - public override void VisitNewLine (NewLineNode newLineNode) - { - throw NotSupportedToConsistency (); - } - - public override void VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective) - { - throw NotSupportedToConsistency (); - } - - public override void VisitDocumentationReference (DocumentationReference documentationReference) - { - throw NotSupportedToConsistency (); - } - - public override void VisitTypeParameterDeclaration (TypeParameterDeclaration typeParameterDeclaration) - { - throw NotSupportedToConsistency (); - } - - public override void VisitConstraint (Constraint constraint) - { - throw NotSupportedToConsistency (); - } - - public override void VisitCSharpTokenNode (CSharpTokenNode cSharpTokenNode) - { - throw NotSupportedToConsistency (); - } - - public override void VisitIdentifier (Identifier identifier) - { - throw NotSupportedToConsistency (); - } - - public override void VisitPatternPlaceholder (AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern) - { - throw NotSupportedToConsistency (); - } - /* - public override void VisitNullNode (AstNode nullNode) - { - throw NotSupportedToConsistency (); - } - *//* - public override void VisitErrorNode (AstNode errorNode) - { - throw NotSupportedToConsistency (); - }*/ - #endregion } } diff --git a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluator.cs b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluator.cs index 26d3b28..2a08ecf 100644 --- a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluator.cs +++ b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluator.cs @@ -31,7 +31,9 @@ using System.Collections.Generic; using Mono.Debugging.Client; -using ICSharpCode.NRefactory.CSharp; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Mono.Debugging.Evaluation { @@ -74,13 +76,13 @@ namespace Mono.Debugging.Evaluation expression = ReplaceExceptionTag (expression, ctx.Options.CurrentExceptionTag); - var expr = new CSharpParser ().ParseExpression (expression); + var expr = SyntaxFactory.ParseExpression (expression); if (expr == null) throw new EvaluatorException ("Could not parse expression '{0}'", expression); var evaluator = new NRefactoryExpressionEvaluatorVisitor (ctx, expression, expectedType, userVariables); - return expr.AcceptVisitor (evaluator); + return evaluator.Visit (expr); } public override string Resolve (DebuggerSession session, SourceLocation location, string exp) @@ -100,15 +102,16 @@ namespace Mono.Debugging.Evaluation expression = ReplaceExceptionTag (expression, session.Options.EvaluationOptions.CurrentExceptionTag); - var expr = new CSharpParser ().ParseExpression (expression); + + var expr = SyntaxFactory.ParseExpression (expression); if (expr == null) return expression; var resolver = new NRefactoryExpressionResolverVisitor (session, location, expression); - expr.AcceptVisitor (resolver); + resolver.Visit (expr); string resolved = resolver.GetResolvedExpression (); - if (resolved == expression && !tryTypeOf && (expr is BinaryOperatorExpression) && IsTypeName (expression)) { + if (resolved == expression && !tryTypeOf && (expr is BinaryExpressionSyntax) && IsTypeName (expression)) { // This is a hack to be able to parse expressions such as "List". The NRefactory parser // can parse a single type name, so a solution is to wrap it around a typeof(). We do it if // the evaluation fails. @@ -134,12 +137,11 @@ namespace Mono.Debugging.Evaluation // Required as a workaround for a bug in the parser (it won't parse simple expressions like numbers) if (!expression.EndsWith (";", StringComparison.Ordinal)) expression += ";"; + ParseOptions options = new CSharpParseOptions (); + var expr = SyntaxFactory.ParseExpression (expression, options: options); - var parser = new CSharpParser (); - parser.ParseExpression (expression); - - if (parser.HasErrors) - return new ValidationResult (false, parser.Errors.First ().Message); + if (expr.ContainsDiagnostics) + return new ValidationResult (false, expr.GetDiagnostics().First ().GetMessage()); return new ValidationResult (true, null); } diff --git a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluatorVisitor.cs b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluatorVisitor.cs index 32340a5..975c890 100644 --- a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluatorVisitor.cs +++ b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionEvaluatorVisitor.cs @@ -30,11 +30,13 @@ using System.Collections.Generic; using Mono.Debugging.Client; -using ICSharpCode.NRefactory.CSharp; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Mono.Debugging.Evaluation { - public class NRefactoryExpressionEvaluatorVisitor : IAstVisitor + public class NRefactoryExpressionEvaluatorVisitor : CSharpSyntaxVisitor { readonly Dictionary userVariables; readonly EvaluationOptions options; @@ -61,7 +63,7 @@ namespace Mono.Debugging.Evaluation return new NotSupportedExpressionException (); } - static string ResolveTypeName (AstType type) + static string ResolveTypeName (SyntaxNode type) { string name = type.ToString (); if (name.StartsWith ("global::", StringComparison.Ordinal)) @@ -127,42 +129,42 @@ namespace Mono.Debugging.Evaluation } } - static object EvaluateOperation (BinaryOperatorType op, double v1, double v2) + static object EvaluateOperation (SyntaxKind op, double v1, double v2) { switch (op) { - case BinaryOperatorType.Add: return v1 + v2; - case BinaryOperatorType.Divide: return v1 / v2; - case BinaryOperatorType.Multiply: return v1 * v2; - case BinaryOperatorType.Subtract: return v1 - v2; - case BinaryOperatorType.GreaterThan: return v1 > v2; - case BinaryOperatorType.GreaterThanOrEqual: return v1 >= v2; - case BinaryOperatorType.LessThan: return v1 < v2; - case BinaryOperatorType.LessThanOrEqual: return v1 <= v2; - case BinaryOperatorType.Equality: return v1 == v2; - case BinaryOperatorType.InEquality: return v1 != v2; + case SyntaxKind.AddExpression: return v1 + v2; + case SyntaxKind.DivideExpression: return v1 / v2; + case SyntaxKind.MultiplyExpression: return v1 * v2; + case SyntaxKind.SubtractExpression: return v1 - v2; + case SyntaxKind.GreaterThanExpression: return v1 > v2; + case SyntaxKind.GreaterThanOrEqualExpression: return v1 >= v2; + case SyntaxKind.LessThanExpression: return v1 < v2; + case SyntaxKind.LessThanOrEqualExpression: return v1 <= v2; + case SyntaxKind.EqualsExpression: return v1 == v2; + case SyntaxKind.NotEqualsExpression: return v1 != v2; default: throw ParseError ("Invalid binary operator."); } } - static object EvaluateOperation (BinaryOperatorType op, long v1, long v2) + static object EvaluateOperation (SyntaxKind op, long v1, long v2) { switch (op) { - case BinaryOperatorType.Add: return v1 + v2; - case BinaryOperatorType.BitwiseAnd: return v1 & v2; - case BinaryOperatorType.BitwiseOr: return v1 | v2; - case BinaryOperatorType.ExclusiveOr: return v1 ^ v2; - case BinaryOperatorType.Divide: return v1 / v2; - case BinaryOperatorType.Modulus: return v1 % v2; - case BinaryOperatorType.Multiply: return v1 * v2; - case BinaryOperatorType.ShiftLeft: return v1 << (int) v2; - case BinaryOperatorType.ShiftRight: return v1 >> (int) v2; - case BinaryOperatorType.Subtract: return v1 - v2; - case BinaryOperatorType.GreaterThan: return v1 > v2; - case BinaryOperatorType.GreaterThanOrEqual: return v1 >= v2; - case BinaryOperatorType.LessThan: return v1 < v2; - case BinaryOperatorType.LessThanOrEqual: return v1 <= v2; - case BinaryOperatorType.Equality: return v1 == v2; - case BinaryOperatorType.InEquality: return v1 != v2; + case SyntaxKind.AddExpression: return v1 + v2; + case SyntaxKind.BitwiseAndExpression: return v1 & v2; + case SyntaxKind.BitwiseOrExpression: return v1 | v2; + case SyntaxKind.ExclusiveOrExpression: return v1 ^ v2; + case SyntaxKind.DivideExpression: return v1 / v2; + case SyntaxKind.ModuloExpression: return v1 % v2; + case SyntaxKind.MultiplyExpression: return v1 * v2; + case SyntaxKind.LeftShiftExpression: return v1 << (int) v2; + case SyntaxKind.RightShiftExpression: return v1 >> (int) v2; + case SyntaxKind.SubtractExpression: return v1 - v2; + case SyntaxKind.GreaterThanExpression: return v1 > v2; + case SyntaxKind.GreaterThanOrEqualExpression: return v1 >= v2; + case SyntaxKind.LessThanExpression: return v1 < v2; + case SyntaxKind.LessThanOrEqualExpression: return v1 <= v2; + case SyntaxKind.EqualsExpression: return v1 == v2; + case SyntaxKind.NotEqualsExpression: return v1 != v2; default: throw ParseError ("Invalid binary operator."); } } @@ -223,7 +225,7 @@ namespace Mono.Debugging.Evaluation return negate ? !retval : retval; } - static ValueReference EvaluateOverloadedOperator (EvaluationContext ctx, string expression, BinaryOperatorType op, object type1, object type2, object targetVal1, object targetVal2, object val1, object val2) + static ValueReference EvaluateOverloadedOperator (EvaluationContext ctx, string expression, SyntaxKind op, object type1, object type2, object targetVal1, object targetVal2, object val1, object val2) { object[] args = new [] { targetVal1, targetVal2 }; object[] argTypes = { type1, type2 }; @@ -231,22 +233,22 @@ namespace Mono.Debugging.Evaluation string methodName = null; switch (op) { - case BinaryOperatorType.BitwiseAnd: methodName = "op_BitwiseAnd"; break; - case BinaryOperatorType.BitwiseOr: methodName = "op_BitwiseOr"; break; - case BinaryOperatorType.ExclusiveOr: methodName = "op_ExclusiveOr"; break; - case BinaryOperatorType.GreaterThan: methodName = "op_GreaterThan"; break; - case BinaryOperatorType.GreaterThanOrEqual: methodName = "op_GreaterThanOrEqual"; break; - case BinaryOperatorType.Equality: methodName = "op_Equality"; break; - case BinaryOperatorType.InEquality: methodName = "op_Inequality"; break; - case BinaryOperatorType.LessThan: methodName = "op_LessThan"; break; - case BinaryOperatorType.LessThanOrEqual: methodName = "op_LessThanOrEqual"; break; - case BinaryOperatorType.Add: methodName = "op_Addition"; break; - case BinaryOperatorType.Subtract: methodName = "op_Subtraction"; break; - case BinaryOperatorType.Multiply: methodName = "op_Multiply"; break; - case BinaryOperatorType.Divide: methodName = "op_Division"; break; - case BinaryOperatorType.Modulus: methodName = "op_Modulus"; break; - case BinaryOperatorType.ShiftLeft: methodName = "op_LeftShift"; break; - case BinaryOperatorType.ShiftRight: methodName = "op_RightShift"; break; + case SyntaxKind.BitwiseAndExpression: methodName = "op_BitwiseAnd"; break; + case SyntaxKind.BitwiseOrExpression: methodName = "op_BitwiseOr"; break; + case SyntaxKind.ExclusiveOrExpression: methodName = "op_ExclusiveOr"; break; + case SyntaxKind.GreaterThanExpression: methodName = "op_GreaterThan"; break; + case SyntaxKind.GreaterThanOrEqualExpression: methodName = "op_GreaterThanOrEqual"; break; + case SyntaxKind.EqualsExpression: methodName = "op_Equality"; break; + case SyntaxKind.NotEqualsExpression: methodName = "op_Inequality"; break; + case SyntaxKind.LessThanExpression: methodName = "op_LessThan"; break; + case SyntaxKind.LessThanOrEqualExpression: methodName = "op_LessThanOrEqual"; break; + case SyntaxKind.AddExpression: methodName = "op_Addition"; break; + case SyntaxKind.SubtractExpression: methodName = "op_Subtraction"; break; + case SyntaxKind.MultiplyExpression: methodName = "op_Multiply"; break; + case SyntaxKind.DivideExpression: methodName = "op_Division"; break; + case SyntaxKind.ModuloExpression: methodName = "op_Modulus"; break; + case SyntaxKind.LeftShiftExpression: methodName = "op_LeftShift"; break; + case SyntaxKind.RightShiftExpression: methodName = "op_RightShift"; break; } if (methodName == null) @@ -265,9 +267,9 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, result); } - ValueReference EvaluateBinaryOperatorExpression (BinaryOperatorType op, ValueReference left, Expression rightExp) + ValueReference EvaluateBinaryOperatorExpression (SyntaxKind op, ValueReference left, ExpressionSyntax rightExp) { - if (op == BinaryOperatorType.ConditionalAnd) { + if (op == SyntaxKind.LogicalAndExpression) { var val = left.ObjectValue; if (!(val is bool)) throw ParseError ("Left operand of logical And must be a boolean."); @@ -275,14 +277,14 @@ namespace Mono.Debugging.Evaluation if (!(bool) val) return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); - var vr = rightExp.AcceptVisitor (this); + var vr = Visit (rightExp); if (vr == null || ctx.Adapter.GetTypeName (ctx, vr.Type) != "System.Boolean") throw ParseError ("Right operand of logical And must be a boolean."); return vr; } - if (op == BinaryOperatorType.ConditionalOr) { + if (op == SyntaxKind.LogicalOrExpression) { var val = left.ObjectValue; if (!(val is bool)) throw ParseError ("Left operand of logical Or must be a boolean."); @@ -290,14 +292,14 @@ namespace Mono.Debugging.Evaluation if ((bool) val) return LiteralValueReference.CreateObjectLiteral (ctx, expression, true); - var vr = rightExp.AcceptVisitor (this); + var vr = Visit (rightExp); if (vr == null || ctx.Adapter.GetTypeName (ctx, vr.Type) != "System.Boolean") throw ParseError ("Right operand of logical Or must be a boolean."); return vr; } - var right = rightExp.AcceptVisitor (this); + var right = Visit (rightExp); var targetVal1 = left.Value; var targetVal2 = right.Value; var type1 = ctx.Adapter.GetValueType (ctx, targetVal1); @@ -308,9 +310,9 @@ namespace Mono.Debugging.Evaluation if (ctx.Adapter.IsNullableType (ctx, type1) && ctx.Adapter.NullableHasValue (ctx, type1, val1)) { if (val2 == null) { - if (op == BinaryOperatorType.Equality) + if (op == SyntaxKind.EqualsExpression) return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); - if (op == BinaryOperatorType.InEquality) + if (op == SyntaxKind.NotEqualsExpression) return LiteralValueReference.CreateObjectLiteral (ctx, expression, true); } @@ -322,9 +324,9 @@ namespace Mono.Debugging.Evaluation if (ctx.Adapter.IsNullableType (ctx, type2) && ctx.Adapter.NullableHasValue (ctx, type2, val2)) { if (val1 == null) { - if (op == BinaryOperatorType.Equality) + if (op == SyntaxKind.EqualsExpression) return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); - if (op == BinaryOperatorType.InEquality) + if (op == SyntaxKind.NotEqualsExpression) return LiteralValueReference.CreateObjectLiteral (ctx, expression, true); } @@ -336,7 +338,7 @@ namespace Mono.Debugging.Evaluation if (val1 is string || val2 is string) { switch (op) { - case BinaryOperatorType.Add: + case SyntaxKind.AddExpression: if (val1 != null && val2 != null) { if (!(val1 is string)) val1 = ctx.Adapter.CallToString (ctx, targetVal1); @@ -352,11 +354,11 @@ namespace Mono.Debugging.Evaluation } return LiteralValueReference.CreateObjectLiteral (ctx, expression, res); - case BinaryOperatorType.Equality: + case SyntaxKind.EqualsExpression: if ((val1 == null || val1 is string) && (val2 == null || val2 is string)) return LiteralValueReference.CreateObjectLiteral (ctx, expression, ((string) val1) == ((string) val2)); break; - case BinaryOperatorType.InEquality: + case SyntaxKind.NotEqualsExpression: if ((val1 == null || val1 is string) && (val2 == null || val2 is string)) return LiteralValueReference.CreateObjectLiteral (ctx, expression, ((string) val1) != ((string) val2)); break; @@ -365,9 +367,9 @@ namespace Mono.Debugging.Evaluation if (val1 == null || (!ctx.Adapter.IsPrimitive (ctx, targetVal1) && !ctx.Adapter.IsEnum (ctx, targetVal1))) { switch (op) { - case BinaryOperatorType.Equality: + case SyntaxKind.EqualsExpression: return LiteralValueReference.CreateObjectLiteral (ctx, expression, CheckEquality (ctx, false, type1, type2, targetVal1, targetVal2, val1, val2)); - case BinaryOperatorType.InEquality: + case SyntaxKind.NotEqualsExpression: return LiteralValueReference.CreateObjectLiteral (ctx, expression, CheckEquality (ctx, true, type1, type2, targetVal1, targetVal2, val1, val2)); default: if (val1 != null && val2 != null) @@ -378,11 +380,11 @@ namespace Mono.Debugging.Evaluation if ((val1 is bool) && (val2 is bool)) { switch (op) { - case BinaryOperatorType.ExclusiveOr: + case SyntaxKind.ExclusiveOrExpression: return LiteralValueReference.CreateObjectLiteral (ctx, expression, (bool) val1 ^ (bool) val2); - case BinaryOperatorType.Equality: + case SyntaxKind.EqualsExpression: return LiteralValueReference.CreateObjectLiteral (ctx, expression, (bool) val1 == (bool) val2); - case BinaryOperatorType.InEquality: + case SyntaxKind.NotEqualsExpression: return LiteralValueReference.CreateObjectLiteral (ctx, expression, (bool) val1 != (bool) val2); } } @@ -432,47 +434,49 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateObjectLiteral (ctx, expression, res); } - static string ResolveType (EvaluationContext ctx, TypeReferenceExpression mre, List args) - { - var memberType = mre.Type as MemberType; + //static string ResolveType (EvaluationContext ctx, TypeReferenceExpression mre, List args) + //{ + // var memberType = mre.Type as MemberType; - if (memberType != null) { - var name = memberType.MemberName; + // if (memberType != null) { + // var name = memberType.MemberName; - if (memberType.TypeArguments.Count > 0) { - name += "`" + memberType.TypeArguments.Count; + // if (memberType.TypeArguments.Count > 0) { + // name += "`" + memberType.TypeArguments.Count; - foreach (var arg in memberType.TypeArguments) { - var resolved = arg.Resolve (ctx); + // foreach (var arg in memberType.TypeArguments) { + // var resolved = arg.Resolve (ctx); - if (resolved == null) - return null; + // if (resolved == null) + // return null; - args.Add (resolved); - } - } + // args.Add (resolved); + // } + // } - return name; - } + // return name; + // } - return mre.ToString (); - } + // return mre.ToString (); + //} - static string ResolveType (EvaluationContext ctx, MemberReferenceExpression mre, List args) + static string ResolveType (EvaluationContext ctx, MemberAccessExpressionSyntax mre, List args) { string parent, name; - if (mre.Target is MemberReferenceExpression) { - parent = ResolveType (ctx, (MemberReferenceExpression) mre.Target, args); - } else if (mre.Target is TypeReferenceExpression) { + if (mre.Expression is MemberAccessExpressionSyntax mae) { + parent = ResolveType (ctx, mae, args); + } else /* TODO? + if (mre.Expression is TypeReferenceExpression) { parent = ResolveType (ctx, (TypeReferenceExpression) mre.Target, args); - } else if (mre.Target is IdentifierExpression) { - parent = ((IdentifierExpression) mre.Target).Identifier; + } else */if (mre.Expression is IdentifierNameSyntax id) { + parent = id.Identifier.ValueText; } else { return null; } - name = parent + "." + mre.MemberName; + name = parent + "." + mre.Name.Identifier.ValueText; + /* if (mre.TypeArguments.Count > 0) { name += "`" + mre.TypeArguments.Count; @@ -484,12 +488,12 @@ namespace Mono.Debugging.Evaluation args.Add (resolved); } - } + }*/ return name; } - static object ResolveType (EvaluationContext ctx, MemberReferenceExpression mre) + static object ResolveType (EvaluationContext ctx, MemberAccessExpressionSyntax mre) { var args = new List (); var name = ResolveType (ctx, mre, args); @@ -503,7 +507,7 @@ namespace Mono.Debugging.Evaluation return ctx.Adapter.GetType (ctx, name); } - static ValueReference ResolveTypeValueReference (EvaluationContext ctx, MemberReferenceExpression mre) + static ValueReference ResolveTypeValueReference (EvaluationContext ctx, MemberAccessExpressionSyntax mre) { object resolved = ResolveType (ctx, mre); @@ -516,18 +520,18 @@ namespace Mono.Debugging.Evaluation throw ParseError ("Could not resolve type: {0}", mre); } - static ValueReference ResolveTypeValueReference (EvaluationContext ctx, AstType type) - { - object resolved = type.Resolve (ctx); + //static ValueReference ResolveTypeValueReference (EvaluationContext ctx, AstType type) + //{ + // object resolved = type.Resolve (ctx); - if (resolved != null) { - ctx.Adapter.ForceLoadType (ctx, resolved); + // if (resolved != null) { + // ctx.Adapter.ForceLoadType (ctx, resolved); - return new TypeValueReference (ctx, resolved); - } + // return new TypeValueReference (ctx, resolved); + // } - throw ParseError ("Could not resolve type: {0}", ResolveTypeName (type)); - } + // throw ParseError ("Could not resolve type: {0}", ResolveTypeName (type)); + //} static object[] UpdateDelayedTypes (object[] types, Tuple[] updates, ref bool alreadyUpdated) { @@ -543,77 +547,46 @@ namespace Mono.Debugging.Evaluation } #region IAstVisitor implementation - - public ValueReference VisitAnonymousMethodExpression (AnonymousMethodExpression anonymousMethodExpression) + public override ValueReference VisitArrayCreationExpression (ArrayCreationExpressionSyntax node) { - throw NotSupported (); - } - - public ValueReference VisitUndocumentedExpression (UndocumentedExpression undocumentedExpression) - { - throw NotSupported (); - } - - public ValueReference VisitArrayCreateExpression (ArrayCreateExpression arrayCreateExpression) - { - var type = arrayCreateExpression.Type.AcceptVisitor (this) as TypeValueReference; + var type = Visit(node.Type.ElementType); if (type == null) throw ParseError ("Invalid type in array creation."); - var lengths = new int [arrayCreateExpression.Arguments.Count]; + var lengths = new int [node.Initializer.Expressions.Count]; for (int i = 0; i < lengths.Length; i++) { - lengths [i] = (int)Convert.ChangeType (arrayCreateExpression.Arguments.ElementAt (i).AcceptVisitor (this).ObjectValue, typeof (int)); + lengths [i] = (int)Convert.ChangeType (Visit(node.Initializer.Expressions[i]).ObjectValue, typeof (int)); } var array = ctx.Adapter.CreateArray (ctx, type.Type, lengths); - if (arrayCreateExpression.Initializer.Elements.Any ()) { + if (node.Initializer.Expressions.Count > 0) { var arrayAdaptor = ctx.Adapter.CreateArrayAdaptor (ctx, array); int index = 0; - foreach (var el in LinearElements(arrayCreateExpression.Initializer.Elements)) { - arrayAdaptor.SetElement (new int [] { index++ }, el.AcceptVisitor (this).Value); + foreach (var el in LinearElements(node.Initializer.Expressions)) { + arrayAdaptor.SetElement (new int [] { index++ }, Visit(el).Value); } } return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, array); } - IEnumerable LinearElements (AstNodeCollection elements) + IEnumerable LinearElements (SeparatedSyntaxList elements) { foreach (var el in elements) { - if (el is ArrayInitializerExpression) - foreach (var el2 in LinearElements (((ArrayInitializerExpression)el).Elements)) { + if (el is ArrayCreationExpressionSyntax arrCre) + foreach (var el2 in LinearElements (arrCre.Initializer.Expressions)) { yield return el2; } else yield return el; } } - public ValueReference VisitArrayInitializerExpression (ArrayInitializerExpression arrayInitializerExpression) - { - throw NotSupported (); - } - - public ValueReference VisitAsExpression (AsExpression asExpression) - { - var type = asExpression.Type.AcceptVisitor (this) as TypeValueReference; - if (type == null) - throw ParseError ("Invalid type in cast."); - - var val = asExpression.Expression.AcceptVisitor (this); - var result = ctx.Adapter.TryCast (ctx, val.Value, type.Type); - - if (result == null) - return new NullValueReference (ctx, type.Type); - - return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, result, type.Type); - } - - public ValueReference VisitAssignmentExpression (AssignmentExpression assignmentExpression) + public override ValueReference VisitAssignmentExpression (AssignmentExpressionSyntax node) { if (!options.AllowMethodEvaluation) throw new ImplicitEvaluationDisabledException (); - var left = assignmentExpression.Left.AcceptVisitor (this); + var left = Visit (node.Left); - if (assignmentExpression.Operator == AssignmentOperatorType.Assign) { - var right = assignmentExpression.Right.AcceptVisitor (this); + if (node.Kind () == SyntaxKind.SimpleAssignmentExpression) { + var right = Visit (node.Right); if (left is UserVariableReference) { left.Value = right.Value; } else { @@ -621,30 +594,30 @@ namespace Mono.Debugging.Evaluation left.Value = castedValue; } } else { - BinaryOperatorType op; - - switch (assignmentExpression.Operator) { - case AssignmentOperatorType.Add: op = BinaryOperatorType.Add; break; - case AssignmentOperatorType.Subtract: op = BinaryOperatorType.Subtract; break; - case AssignmentOperatorType.Multiply: op = BinaryOperatorType.Multiply; break; - case AssignmentOperatorType.Divide: op = BinaryOperatorType.Divide; break; - case AssignmentOperatorType.Modulus: op = BinaryOperatorType.Modulus; break; - case AssignmentOperatorType.ShiftLeft: op = BinaryOperatorType.ShiftLeft; break; - case AssignmentOperatorType.ShiftRight: op = BinaryOperatorType.ShiftRight; break; - case AssignmentOperatorType.BitwiseAnd: op = BinaryOperatorType.BitwiseAnd; break; - case AssignmentOperatorType.BitwiseOr: op = BinaryOperatorType.BitwiseOr; break; - case AssignmentOperatorType.ExclusiveOr: op = BinaryOperatorType.ExclusiveOr; break; + SyntaxKind op; + + switch (node.Kind ()) { + case SyntaxKind.AddAssignmentExpression: op = SyntaxKind.AddExpression; break; + case SyntaxKind.SubtractAssignmentExpression: op = SyntaxKind.SubtractExpression; break; + case SyntaxKind.MultiplyAssignmentExpression: op = SyntaxKind.MultiplyExpression; break; + case SyntaxKind.DivideAssignmentExpression: op = SyntaxKind.DivideExpression; break; + case SyntaxKind.ModuloAssignmentExpression: op = SyntaxKind.ModuloExpression; break; + case SyntaxKind.LeftShiftAssignmentExpression: op = SyntaxKind.LeftShiftExpression; break; + case SyntaxKind.RightShiftAssignmentExpression: op = SyntaxKind.RightShiftExpression; break; + case SyntaxKind.AndAssignmentExpression: op = SyntaxKind.BitwiseAndExpression; break; + case SyntaxKind.OrAssignmentExpression: op = SyntaxKind.BitwiseOrExpression; break; + case SyntaxKind.ExclusiveOrAssignmentExpression: op = SyntaxKind.ExclusiveOrExpression; break; default: throw ParseError ("Invalid operator in assignment."); } - var result = EvaluateBinaryOperatorExpression (op, left, assignmentExpression.Right); + var result = EvaluateBinaryOperatorExpression (op, left, node.Right); left.Value = result.Value; } return left; } - public ValueReference VisitBaseReferenceExpression (BaseReferenceExpression baseReferenceExpression) + public override ValueReference VisitBaseExpression (BaseExpressionSyntax node) { var self = ctx.Adapter.GetThisReference (ctx); @@ -654,20 +627,51 @@ namespace Mono.Debugging.Evaluation throw ParseError ("'base' reference not available in static methods."); } - public ValueReference VisitBinaryOperatorExpression (BinaryOperatorExpression binaryOperatorExpression) + public override ValueReference VisitBinaryExpression (BinaryExpressionSyntax node) { - var left = binaryOperatorExpression.Left.AcceptVisitor (this); + if (node.IsKind (SyntaxKind.AsExpression)) { + var type = Visit (node.Right) as TypeValueReference; + if (type == null) + throw ParseError ("Invalid type in cast."); - return EvaluateBinaryOperatorExpression (binaryOperatorExpression.Operator, left, binaryOperatorExpression.Right); + var val = Visit (node.Left); + var result = ctx.Adapter.TryCast (ctx, val.Value, type.Type); + + if (result == null) + return new NullValueReference (ctx, type.Type); + + return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, result, type.Type); + } + if (node.IsKind (SyntaxKind.IsExpression)) { + var type = (Visit (node.Right) as TypeValueReference)?.Type; + if (type == null) + throw ParseError ("Invalid type in 'is' expression."); + if (ctx.Adapter.IsNullableType (ctx, type)) + type = ctx.Adapter.GetGenericTypeArguments (ctx, type).Single (); + var val = Visit (node.Left).Value; + if (ctx.Adapter.IsNull (ctx, val)) + return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); + var valueIsPrimitive = ctx.Adapter.IsPrimitive (ctx, val); + var typeIsPrimitive = ctx.Adapter.IsPrimitiveType (type); + if (valueIsPrimitive != typeIsPrimitive) + return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); + if (typeIsPrimitive) + return LiteralValueReference.CreateObjectLiteral (ctx, expression, ctx.Adapter.GetTypeName (ctx, type) == ctx.Adapter.GetValueTypeName (ctx, val)); + return LiteralValueReference.CreateObjectLiteral (ctx, expression, ctx.Adapter.TryCast (ctx, val, type) != null); + } + + var left = this.Visit (node.Left); + + return EvaluateBinaryOperatorExpression (node.Kind (), left, node.Right); } - public ValueReference VisitCastExpression (CastExpression castExpression) + public override ValueReference VisitCastExpression (CastExpressionSyntax node) { - var type = castExpression.Type.AcceptVisitor (this) as TypeValueReference; + var type = Visit(node.Type) as TypeValueReference; if (type == null) throw ParseError ("Invalid type in cast."); - var val = castExpression.Expression.AcceptVisitor (this); + var val = Visit(node.Expression); object result = ctx.Adapter.TryCast (ctx, val.Value, type.Type); if (result == null) throw ParseError ("Invalid cast."); @@ -675,26 +679,26 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, result, type.Type); } - public ValueReference VisitCheckedExpression (CheckedExpression checkedExpression) + public override ValueReference VisitCheckedExpression (CheckedExpressionSyntax node) { throw NotSupported (); } - public ValueReference VisitConditionalExpression (ConditionalExpression conditionalExpression) + public override ValueReference VisitConditionalExpression (ConditionalExpressionSyntax node) { - ValueReference val = conditionalExpression.Condition.AcceptVisitor (this); + ValueReference val = Visit(node.Condition); if (val is TypeValueReference) throw NotSupported (); - if ((bool) val.ObjectValue) - return conditionalExpression.TrueExpression.AcceptVisitor (this); + if ((bool)val.ObjectValue) + return Visit (node.WhenTrue);; - return conditionalExpression.FalseExpression.AcceptVisitor (this); + return Visit (node.WhenFalse); } - public ValueReference VisitDefaultValueExpression (DefaultValueExpression defaultValueExpression) + public override ValueReference VisitDefaultExpression (DefaultExpressionSyntax node) { - var type = defaultValueExpression.Type.AcceptVisitor (this) as TypeValueReference; + var type = Visit(node.Type) as TypeValueReference; if (type == null) throw ParseError ("Invalid type in 'default' expression."); @@ -722,14 +726,9 @@ namespace Mono.Debugging.Evaluation } } - public ValueReference VisitDirectionExpression (DirectionExpression directionExpression) - { - throw NotSupported (); - } - - public ValueReference VisitIdentifierExpression (IdentifierExpression identifierExpression) + public override ValueReference VisitIdentifierName (IdentifierNameSyntax node) { - var name = identifierExpression.Identifier; + var name = node.Identifier.ValueText; if (name == "__EXCEPTION_OBJECT__") return ctx.Adapter.GetCurrentException (ctx); @@ -798,28 +797,28 @@ namespace Mono.Debugging.Evaluation throw ParseError ("Unknown identifier: {0}", name); } - public ValueReference VisitIndexerExpression (IndexerExpression indexerExpression) + public override ValueReference VisitElementAccessExpression (ElementAccessExpressionSyntax node) { int n = 0; - var target = indexerExpression.Target.AcceptVisitor (this); + var target = Visit(node.Expression); if (target is TypeValueReference) throw NotSupported (); if (ctx.Adapter.IsArray (ctx, target.Value)) { - int[] indexes = new int [indexerExpression.Arguments.Count]; + int[] indexes = new int [node.ArgumentList.Arguments.Count]; - foreach (var arg in indexerExpression.Arguments) { - var index = arg.AcceptVisitor (this); + foreach (var arg in node.ArgumentList.Arguments) { + var index = Visit(arg); indexes[n++] = (int) Convert.ChangeType (index.ObjectValue, typeof (int)); } return new ArrayValueReference (ctx, target.Value, indexes); } - object[] args = new object [indexerExpression.Arguments.Count]; - foreach (var arg in indexerExpression.Arguments) - args[n++] = arg.AcceptVisitor (this).Value; + object[] args = new object [node.ArgumentList.Arguments.Count]; + foreach (var arg in node.ArgumentList.Arguments) + args[n++] = Visit (arg).Value; var indexer = ctx.Adapter.GetIndexerReference (ctx, target.Value, target.Type, args); if (indexer == null) @@ -828,43 +827,33 @@ namespace Mono.Debugging.Evaluation return indexer; } - string ResolveMethodName (MemberReferenceExpression method, out object[] typeArgs) + string ResolveMethodName (SyntaxNode invocationExpression, out object[] typeArgs) { - if (method.TypeArguments.Count > 0) { - var args = new List (); - - foreach (var arg in method.TypeArguments) { - var type = arg.AcceptVisitor (this); - args.Add (type.Type); - } - - typeArgs = args.ToArray (); - } else { + if (invocationExpression is IdentifierNameSyntax id) { typeArgs = null; + return id.Identifier.ValueText; } + if (invocationExpression is GenericNameSyntax gns) { + if (gns.Arity > 0) { + var args = new List (); - return method.MemberName; - } - - string ResolveMethodName (IdentifierExpression method, out object[] typeArgs) - { - if (method.TypeArguments.Count > 0) { - var args = new List (); + foreach (var arg in gns.TypeArgumentList.Arguments) { + var type = Visit(arg); + args.Add (type.Type); + } - foreach (var arg in method.TypeArguments) { - var type = arg.AcceptVisitor (this); - args.Add (type.Type); + typeArgs = args.ToArray (); + } else { + typeArgs = null; } - - typeArgs = args.ToArray (); - } else { - typeArgs = null; + return gns.Identifier.ValueText; } - return method.Identifier; + typeArgs = null; + return invocationExpression.ToString (); } - public ValueReference VisitInvocationExpression (InvocationExpression invocationExpression) + public override ValueReference VisitInvocationExpression (InvocationExpressionSyntax node) { if (!options.AllowMethodEvaluation) throw new ImplicitEvaluationDisabledException (); @@ -874,13 +863,13 @@ namespace Mono.Debugging.Evaluation ValueReference target = null; string methodName; - var types = new object [invocationExpression.Arguments.Count]; - var args = new object [invocationExpression.Arguments.Count]; + var types = new object [node.ArgumentList.Arguments.Count]; + var args = new object [node.ArgumentList.Arguments.Count]; object[] typeArgs = null; int n = 0; - foreach (var arg in invocationExpression.Arguments) { - var vref = arg.AcceptVisitor (this); + foreach (var arg in node.ArgumentList.Arguments) { + var vref = this.Visit (arg); args[n] = vref.Value; types[n] = ctx.Adapter.GetValueType (ctx, args[n]); @@ -891,14 +880,12 @@ namespace Mono.Debugging.Evaluation object vtype = null; Tuple[] resolvedLambdaTypes; - if (invocationExpression.Target is MemberReferenceExpression) { - var field = (MemberReferenceExpression) invocationExpression.Target; - target = field.Target.AcceptVisitor (this); - if (field.Target is BaseReferenceExpression) + if (node.Expression is MemberAccessExpressionSyntax field) { + target = Visit (field.Expression); + if (field.Expression is BaseExpressionSyntax) invokeBaseMethod = true; methodName = ResolveMethodName (field, out typeArgs); - } else if (invocationExpression.Target is IdentifierExpression) { - var method = (IdentifierExpression) invocationExpression.Target; + } else if (node.Expression is IdentifierNameSyntax method) { var vref = ctx.Adapter.GetThisReference (ctx); methodName = ResolveMethodName (method, out typeArgs); @@ -991,39 +978,20 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateVoidReturnLiteral (ctx, expression); } - public ValueReference VisitIsExpression (IsExpression isExpression) - { - var type = (isExpression.Type.AcceptVisitor (this) as TypeValueReference)?.Type; - if (type == null) - throw ParseError ("Invalid type in 'is' expression."); - if (ctx.Adapter.IsNullableType (ctx, type)) - type = ctx.Adapter.GetGenericTypeArguments (ctx, type).Single (); - var val = isExpression.Expression.AcceptVisitor (this).Value; - if (ctx.Adapter.IsNull (ctx, val)) - return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); - var valueIsPrimitive = ctx.Adapter.IsPrimitive (ctx, val); - var typeIsPrimitive = ctx.Adapter.IsPrimitiveType (type); - if (valueIsPrimitive != typeIsPrimitive) - return LiteralValueReference.CreateObjectLiteral (ctx, expression, false); - if (typeIsPrimitive) - return LiteralValueReference.CreateObjectLiteral (ctx, expression, ctx.Adapter.GetTypeName (ctx, type) == ctx.Adapter.GetValueTypeName (ctx, val)); - return LiteralValueReference.CreateObjectLiteral (ctx, expression, ctx.Adapter.TryCast (ctx, val, type) != null); - } - public ValueReference VisitLambdaExpression (LambdaExpression lambdaExpression) + public override ValueReference VisitSimpleLambdaExpression (SimpleLambdaExpressionSyntax node) { - if (lambdaExpression.IsAsync) + if (node.AsyncKeyword != null) throw NotSupported (); - AstNode parent = lambdaExpression.Parent; - while (parent != null && parent is ParenthesizedExpression) + var parent = node.Parent; + while (parent != null && parent is ParenthesizedExpressionSyntax) parent = parent.Parent; - if (parent is InvocationExpression || parent is CastExpression) { + if (parent is InvocationExpressionSyntax || parent is CastExpressionSyntax) { var writer = new System.IO.StringWriter (); var visitor = new LambdaBodyOutputVisitor (ctx, userVariables, writer); - - lambdaExpression.AcceptVisitor (visitor); + visitor.Visit (node); var body = writer.ToString (); var values = visitor.GetLocalValues (); object val = ctx.Adapter.CreateDelayedLambdaValue (ctx, body, values); @@ -1034,13 +1002,14 @@ namespace Mono.Debugging.Evaluation throw NotSupported (); } - public ValueReference VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression) + + public override ValueReference VisitMemberAccessExpression (MemberAccessExpressionSyntax node) { - if (memberReferenceExpression.TypeArguments.Count > 0) - return ResolveTypeValueReference (ctx, memberReferenceExpression); + if (node.Name is GenericNameSyntax gns) + return ResolveTypeValueReference (ctx, node); - var target = memberReferenceExpression.Target.AcceptVisitor (this); - var member = target.GetChild (memberReferenceExpression.MemberName, ctx.Options); + var target = Visit (node.Expression); + var member = target.GetChild (node.Name.Identifier.ValueText, ctx.Options); if (member == null) { if (!(target is TypeValueReference)) { @@ -1048,77 +1017,46 @@ namespace Mono.Debugging.Evaluation throw new EvaluatorException ("{0} is null", target.Name); } - throw ParseError ("Unknown member: {0}", memberReferenceExpression.MemberName); + throw ParseError ("Unknown member: {0}", node.Name.Identifier.ValueText); } return member; } - public ValueReference VisitNamedArgumentExpression (NamedArgumentExpression namedArgumentExpression) - { - throw NotSupported (); - } - - public ValueReference VisitNamedExpression (NamedExpression namedExpression) + public override ValueReference VisitLiteralExpression (LiteralExpressionSyntax node) { - throw NotSupported (); + if (node.Kind() == SyntaxKind.NullLiteralExpression) + return new NullValueReference (ctx, ctx.Adapter.GetType (ctx, "System.Object")); + return base.VisitLiteralExpression (node); } - public ValueReference VisitNullReferenceExpression (NullReferenceExpression nullReferenceExpression) + public override ValueReference VisitObjectCreationExpression (ObjectCreationExpressionSyntax node) { - return new NullValueReference (ctx, ctx.Adapter.GetType (ctx, "System.Object")); - } - - public ValueReference VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression) - { - var type = objectCreateExpression.Type.AcceptVisitor (this) as TypeValueReference; + var type = Visit(node.Type) as TypeValueReference; var args = new List (); - foreach (var arg in objectCreateExpression.Arguments) { - var val = arg.AcceptVisitor (this); + foreach (var arg in node.ArgumentList.Arguments) { + var val = Visit(arg); args.Add (val != null ? val.Value : null); } return LiteralValueReference.CreateTargetObjectLiteral (ctx, expression, ctx.Adapter.CreateValue (ctx, type.Type, args.ToArray ())); } - public ValueReference VisitAnonymousTypeCreateExpression (AnonymousTypeCreateExpression anonymousTypeCreateExpression) - { - throw NotSupported (); - } - - public ValueReference VisitParenthesizedExpression (ParenthesizedExpression parenthesizedExpression) - { - return parenthesizedExpression.Expression.AcceptVisitor (this); - } - - public ValueReference VisitPointerReferenceExpression (PointerReferenceExpression pointerReferenceExpression) + public override ValueReference VisitParenthesizedExpression (ParenthesizedExpressionSyntax node) { - throw NotSupported (); + return Visit (node.Expression); } - public ValueReference VisitPrimitiveExpression (PrimitiveExpression primitiveExpression) + public override ValueReference VisitPredefinedType (PredefinedTypeSyntax node) { - if (primitiveExpression.Value != null) - return LiteralValueReference.CreateObjectLiteral (ctx, expression, primitiveExpression.Value); - if (expectedType != null) return new NullValueReference (ctx, expectedType); return new NullValueReference (ctx, ctx.Adapter.GetType (ctx, "System.Object")); } - public ValueReference VisitSizeOfExpression (SizeOfExpression sizeOfExpression) - { - throw NotSupported (); - } - - public ValueReference VisitStackAllocExpression (StackAllocExpression stackAllocExpression) - { - throw NotSupported (); - } - - public ValueReference VisitThisReferenceExpression (ThisReferenceExpression thisReferenceExpression) + public override ValueReference VisitThisExpression (ThisExpressionSyntax node) { var self = ctx.Adapter.GetThisReference (ctx); @@ -1128,10 +1066,10 @@ namespace Mono.Debugging.Evaluation return self; } - public ValueReference VisitTypeOfExpression (TypeOfExpression typeOfExpression) + public override ValueReference VisitTypeOfExpression (TypeOfExpressionSyntax node) { - var name = ResolveTypeName (typeOfExpression.Type); - var type = typeOfExpression.Type.Resolve (ctx); + var name = ResolveTypeName (node.Type); + var type = node.Type.Resolve (ctx); if (type == null) throw ParseError ("Could not load type: {0}", name); @@ -1143,35 +1081,76 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateTargetObjectLiteral (ctx, name, result); } - public ValueReference VisitTypeReferenceExpression (TypeReferenceExpression typeReferenceExpression) - { - var type = typeReferenceExpression.Type.Resolve (ctx); + //public ValueReference VisitTypeReferenceExpression (TypeReferenceExpression typeReferenceExpression) + //{ + // var type = typeReferenceExpression.Type.Resolve (ctx); - if (type != null) { - ctx.Adapter.ForceLoadType (ctx, type); + // if (type != null) { + // ctx.Adapter.ForceLoadType (ctx, type); - return new TypeValueReference (ctx, type); - } + // return new TypeValueReference (ctx, type); + // } + + // var name = ResolveTypeName (typeReferenceExpression.Type); + + // // Assume it is a namespace. + // return new NamespaceValueReference (ctx, name); + //} + + public override ValueReference VisitPostfixUnaryExpression (PostfixUnaryExpressionSyntax node) + { + var vref = Visit (node.Operand); + var val = vref.ObjectValue; + object newVal; + long num; - var name = ResolveTypeName (typeReferenceExpression.Type); + switch (node.Kind ()) { + case SyntaxKind.PostDecrementExpression: + if (val is decimal) { + newVal = ((decimal)val) - 1; + } else if (val is double) { + newVal = ((double)val) - 1; + } else if (val is float) { + newVal = ((float)val) - 1; + } else { + num = GetInteger (val) - 1; + newVal = Convert.ChangeType (num, val.GetType ()); + } + vref.Value = ctx.Adapter.CreateValue (ctx, newVal); + break; + case SyntaxKind.PostIncrementExpression: + if (val is decimal) { + newVal = ((decimal)val) + 1; + } else if (val is double) { + newVal = ((double)val) + 1; + } else if (val is float) { + newVal = ((float)val) + 1; + } else { + num = GetInteger (val) + 1; + newVal = Convert.ChangeType (num, val.GetType ()); + } + vref.Value = ctx.Adapter.CreateValue (ctx, newVal); + break; + default: + throw NotSupported (); + } - // Assume it is a namespace. - return new NamespaceValueReference (ctx, name); + return LiteralValueReference.CreateObjectLiteral (ctx, expression, val); } - public ValueReference VisitUnaryOperatorExpression (UnaryOperatorExpression unaryOperatorExpression) + public override ValueReference VisitPrefixUnaryExpression (PrefixUnaryExpressionSyntax node) { - var vref = unaryOperatorExpression.Expression.AcceptVisitor (this); + var vref = Visit (node.Operand); var val = vref.ObjectValue; object newVal; long num; - switch (unaryOperatorExpression.Operator) { - case UnaryOperatorType.BitNot: + switch (node.Kind ()) { + case SyntaxKind.BitwiseNotExpression: num = ~GetInteger (val); val = Convert.ChangeType (num, val.GetType ()); break; - case UnaryOperatorType.Minus: + case SyntaxKind.UnaryMinusExpression: if (val is decimal) { val = -(decimal)val; } else if (val is double) { @@ -1183,26 +1162,13 @@ namespace Mono.Debugging.Evaluation val = Convert.ChangeType (num, val.GetType ()); } break; - case UnaryOperatorType.Not: + case SyntaxKind.LogicalNotExpression: if (!(val is bool)) throw ParseError ("Expected boolean type in Not operator."); - val = !(bool) val; + val = !(bool)val; break; - case UnaryOperatorType.PostDecrement: - if (val is decimal) { - newVal = ((decimal)val) - 1; - } else if (val is double) { - newVal = ((double)val) - 1; - } else if (val is float) { - newVal = ((float)val) - 1; - } else { - num = GetInteger (val) - 1; - newVal = Convert.ChangeType (num, val.GetType ()); - } - vref.Value = ctx.Adapter.CreateValue (ctx, newVal); - break; - case UnaryOperatorType.Decrement: + case SyntaxKind.PreDecrementExpression: if (val is decimal) { val = ((decimal)val) - 1; } else if (val is double) { @@ -1215,20 +1181,7 @@ namespace Mono.Debugging.Evaluation } vref.Value = ctx.Adapter.CreateValue (ctx, val); break; - case UnaryOperatorType.PostIncrement: - if (val is decimal) { - newVal = ((decimal)val) + 1; - } else if (val is double) { - newVal = ((double)val) + 1; - } else if (val is float) { - newVal = ((float)val) + 1; - } else { - num = GetInteger (val) + 1; - newVal = Convert.ChangeType (num, val.GetType ()); - } - vref.Value = ctx.Adapter.CreateValue (ctx, newVal); - break; - case UnaryOperatorType.Increment: + case SyntaxKind.PreIncrementExpression: if (val is decimal) { val = ((decimal)val) + 1; } else if (val is double) { @@ -1241,7 +1194,7 @@ namespace Mono.Debugging.Evaluation } vref.Value = ctx.Adapter.CreateValue (ctx, val); break; - case UnaryOperatorType.Plus: + case SyntaxKind.UnaryPlusExpression: break; default: throw NotSupported (); @@ -1250,432 +1203,10 @@ namespace Mono.Debugging.Evaluation return LiteralValueReference.CreateObjectLiteral (ctx, expression, val); } - public ValueReference VisitUncheckedExpression (UncheckedExpression uncheckedExpression) - { - throw NotSupported (); - } - - [Obsolete] - public ValueReference VisitEmptyExpression (EmptyExpression emptyExpression) - { - throw NotSupported (); - } - - public ValueReference VisitQueryExpression (QueryExpression queryExpression) - { - throw NotSupported (); - } - - public ValueReference VisitQueryContinuationClause (QueryContinuationClause queryContinuationClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryFromClause (QueryFromClause queryFromClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryLetClause (QueryLetClause queryLetClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryWhereClause (QueryWhereClause queryWhereClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryJoinClause (QueryJoinClause queryJoinClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryOrderClause (QueryOrderClause queryOrderClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryOrdering (QueryOrdering queryOrdering) - { - throw NotSupported (); - } - - public ValueReference VisitQuerySelectClause (QuerySelectClause querySelectClause) - { - throw NotSupported (); - } - - public ValueReference VisitQueryGroupClause (QueryGroupClause queryGroupClause) - { - throw NotSupported (); - } - - public ValueReference VisitAttribute (ICSharpCode.NRefactory.CSharp.Attribute attribute) - { - throw NotSupported (); - } - - public ValueReference VisitAttributeSection (AttributeSection attributeSection) - { - throw NotSupported (); - } - - public ValueReference VisitDelegateDeclaration (DelegateDeclaration delegateDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitNamespaceDeclaration (NamespaceDeclaration namespaceDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitTypeDeclaration (TypeDeclaration typeDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitUsingAliasDeclaration (UsingAliasDeclaration usingAliasDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitUsingDeclaration (UsingDeclaration usingDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitExternAliasDeclaration (ExternAliasDeclaration externAliasDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitBlockStatement (BlockStatement blockStatement) - { - throw NotSupported (); - } - - public ValueReference VisitBreakStatement (BreakStatement breakStatement) - { - throw NotSupported (); - } - - public ValueReference VisitCheckedStatement (CheckedStatement checkedStatement) - { - throw NotSupported (); - } - - public ValueReference VisitContinueStatement (ContinueStatement continueStatement) - { - throw NotSupported (); - } - - public ValueReference VisitDoWhileStatement (DoWhileStatement doWhileStatement) - { - throw NotSupported (); - } - - public ValueReference VisitEmptyStatement (EmptyStatement emptyStatement) - { - throw NotSupported (); - } - - public ValueReference VisitExpressionStatement (ExpressionStatement expressionStatement) - { - throw NotSupported (); - } - - public ValueReference VisitFixedStatement (FixedStatement fixedStatement) - { - throw NotSupported (); - } - - public ValueReference VisitForeachStatement (ForeachStatement foreachStatement) - { - throw NotSupported (); - } - - public ValueReference VisitForStatement (ForStatement forStatement) - { - throw NotSupported (); - } - - public ValueReference VisitGotoCaseStatement (GotoCaseStatement gotoCaseStatement) - { - throw NotSupported (); - } - - public ValueReference VisitGotoDefaultStatement (GotoDefaultStatement gotoDefaultStatement) - { - throw NotSupported (); - } - - public ValueReference VisitGotoStatement (GotoStatement gotoStatement) - { - throw NotSupported (); - } - - public ValueReference VisitIfElseStatement (IfElseStatement ifElseStatement) - { - throw NotSupported (); - } - - public ValueReference VisitLabelStatement (LabelStatement labelStatement) - { - throw NotSupported (); - } - - public ValueReference VisitLockStatement (LockStatement lockStatement) - { - throw NotSupported (); - } - - public ValueReference VisitReturnStatement (ReturnStatement returnStatement) - { - throw NotSupported (); - } - - public ValueReference VisitSwitchStatement (SwitchStatement switchStatement) - { - throw NotSupported (); - } - - public ValueReference VisitSwitchSection (SwitchSection switchSection) - { - throw NotSupported (); - } - - public ValueReference VisitCaseLabel (CaseLabel caseLabel) - { - throw NotSupported (); - } - - public ValueReference VisitThrowStatement (ThrowStatement throwStatement) - { - throw NotSupported (); - } - - public ValueReference VisitTryCatchStatement (TryCatchStatement tryCatchStatement) - { - throw NotSupported (); - } - - public ValueReference VisitCatchClause (CatchClause catchClause) - { - throw NotSupported (); - } - - public ValueReference VisitUncheckedStatement (UncheckedStatement uncheckedStatement) - { - throw NotSupported (); - } - - public ValueReference VisitUnsafeStatement (UnsafeStatement unsafeStatement) - { - throw NotSupported (); - } - - public ValueReference VisitUsingStatement (UsingStatement usingStatement) - { - throw NotSupported (); - } - - public ValueReference VisitVariableDeclarationStatement (VariableDeclarationStatement variableDeclarationStatement) - { - throw NotSupported (); - } - - public ValueReference VisitWhileStatement (WhileStatement whileStatement) - { - throw NotSupported (); - } - - public ValueReference VisitYieldBreakStatement (YieldBreakStatement yieldBreakStatement) - { - throw NotSupported (); - } - - public ValueReference VisitYieldReturnStatement (YieldReturnStatement yieldReturnStatement) - { - throw NotSupported (); - } - - public ValueReference VisitAccessor (Accessor accessor) - { - throw NotSupported (); - } - - public ValueReference VisitConstructorDeclaration (ConstructorDeclaration constructorDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitConstructorInitializer (ConstructorInitializer constructorInitializer) - { - throw NotSupported (); - } - - public ValueReference VisitDestructorDeclaration (DestructorDeclaration destructorDeclaration) + public override ValueReference DefaultVisit (SyntaxNode node) { throw NotSupported (); } - - public ValueReference VisitEnumMemberDeclaration (EnumMemberDeclaration enumMemberDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitEventDeclaration (EventDeclaration eventDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitCustomEventDeclaration (CustomEventDeclaration customEventDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitFieldDeclaration (FieldDeclaration fieldDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitIndexerDeclaration (IndexerDeclaration indexerDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitMethodDeclaration (MethodDeclaration methodDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitOperatorDeclaration (OperatorDeclaration operatorDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitParameterDeclaration (ParameterDeclaration parameterDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitPropertyDeclaration (PropertyDeclaration propertyDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitVariableInitializer (VariableInitializer variableInitializer) - { - throw NotSupported (); - } - - public ValueReference VisitFixedFieldDeclaration (FixedFieldDeclaration fixedFieldDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitFixedVariableInitializer (FixedVariableInitializer fixedVariableInitializer) - { - throw NotSupported (); - } - - public ValueReference VisitSyntaxTree (SyntaxTree syntaxTree) - { - throw NotSupported (); - } - - public ValueReference VisitSimpleType (SimpleType simpleType) - { - return ResolveTypeValueReference (ctx, simpleType); - } - - public ValueReference VisitMemberType (MemberType memberType) - { - return ResolveTypeValueReference (ctx, memberType); - } - - public ValueReference VisitComposedType (ComposedType composedType) - { - return ResolveTypeValueReference (ctx, composedType); - } - - public ValueReference VisitArraySpecifier (ArraySpecifier arraySpecifier) - { - throw NotSupported (); - } - - public ValueReference VisitPrimitiveType (PrimitiveType primitiveType) - { - return ResolveTypeValueReference (ctx, primitiveType); - } - - public ValueReference VisitComment (Comment comment) - { - throw NotSupported (); - } - - public ValueReference VisitWhitespace (WhitespaceNode whitespaceNode) - { - throw NotSupported (); - } - - public ValueReference VisitText (TextNode textNode) - { - throw NotSupported (); - } - - public ValueReference VisitNewLine (NewLineNode newLineNode) - { - throw NotSupported (); - } - - public ValueReference VisitPreProcessorDirective (PreProcessorDirective preProcessorDirective) - { - throw NotSupported (); - } - - public ValueReference VisitDocumentationReference (DocumentationReference documentationReference) - { - throw NotSupported (); - } - - public ValueReference VisitTypeParameterDeclaration (TypeParameterDeclaration typeParameterDeclaration) - { - throw NotSupported (); - } - - public ValueReference VisitConstraint (Constraint constraint) - { - throw NotSupported (); - } - - public ValueReference VisitCSharpTokenNode (CSharpTokenNode cSharpTokenNode) - { - throw NotSupported (); - } - - public ValueReference VisitIdentifier (Identifier identifier) - { - throw NotSupported (); - } - - public ValueReference VisitPatternPlaceholder (AstNode placeholder, ICSharpCode.NRefactory.PatternMatching.Pattern pattern) - { - throw NotSupported (); - } - - public ValueReference VisitNullNode(AstNode nullNode) - { - throw NotSupported (); - } - - public ValueReference VisitErrorNode (AstNode errorNode) - { - throw NotSupported (); - } - #endregion } -} +} \ No newline at end of file diff --git a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionResolverVisitor.cs b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionResolverVisitor.cs index 7d9d61e..98d4a58 100644 --- a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionResolverVisitor.cs +++ b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExpressionResolverVisitor.cs @@ -27,15 +27,17 @@ using System; using System.Text; using System.Collections.Generic; -using ICSharpCode.NRefactory.CSharp; +using Microsoft.CodeAnalysis.CSharp; using Mono.Debugging.Client; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis; namespace Mono.Debugging.Evaluation { // FIXME: if we passed the DebuggerSession and SourceLocation into the NRefactoryExpressionEvaluatorVisitor, // we wouldn't need to do this resolve step. - public class NRefactoryExpressionResolverVisitor : DepthFirstAstVisitor + public class NRefactoryExpressionResolverVisitor : CSharpSyntaxWalker { readonly List replacements = new List (); readonly SourceLocation location; @@ -114,55 +116,31 @@ namespace Mono.Debugging.Evaluation } } - void ReplaceType (AstType type) + void ReplaceType (SyntaxNode type) { - int length = type.EndLocation.Column - type.StartLocation.Column; - int offset = type.StartLocation.Column - 1; + int length = type.Span.Length; + int offset = type.Span.Start; - ReplaceType (type.ToString (), 0, offset, length); + ReplaceType (type.ToString(), 0, offset, length); } - public override void VisitIdentifierExpression (IdentifierExpression identifierExpression) + public override void VisitIdentifierName (IdentifierNameSyntax node) { - base.VisitIdentifierExpression (identifierExpression); + base.VisitIdentifierName (node); + int length = node.Span.Length; + int offset = node.Span.Start; - int length = identifierExpression.IdentifierToken.EndLocation.Column - identifierExpression.IdentifierToken.StartLocation.Column; - int offset = identifierExpression.IdentifierToken.StartLocation.Column - 1; - - ReplaceType (identifierExpression.Identifier, identifierExpression.TypeArguments.Count, offset, length); + ReplaceType (node.Identifier.ValueText, node.Arity, offset, length); } - public override void VisitTypeReferenceExpression (TypeReferenceExpression typeReferenceExpression) + public override void VisitSimpleBaseType (SimpleBaseTypeSyntax node) { - ReplaceType (typeReferenceExpression.Type); + ReplaceType (node); } - public override void VisitComposedType (ComposedType composedType) + public override void VisitPredefinedType (PredefinedTypeSyntax node) { - // Note: we specifically do not handle this case because the 'base' implementation will eventually - // call VisitMemberType() or VisitSimpleType() on the ComposedType.BaseType which is all we really - // care to resolve. - base.VisitComposedType (composedType); - } - - public override void VisitMemberType (MemberType memberType) - { - base.VisitMemberType (memberType); - if (parentType == null) - return; - int length = memberType.MemberNameToken.EndLocation.Column - memberType.MemberNameToken.StartLocation.Column; - int offset = memberType.MemberNameToken.StartLocation.Column - 1; - ReplaceType (parentType + "." + memberType.MemberName, memberType.TypeArguments.Count, offset, length, true); - } - - public override void VisitSimpleType (SimpleType simpleType) - { - base.VisitSimpleType (simpleType); - - int length = simpleType.IdentifierToken.EndLocation.Column - simpleType.IdentifierToken.StartLocation.Column; - int offset = simpleType.IdentifierToken.StartLocation.Column - 1; - - ReplaceType (simpleType.Identifier, simpleType.TypeArguments.Count, offset, length); + ReplaceType (node); } } -} +} \ No newline at end of file diff --git a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExtensions.cs b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExtensions.cs index c264217..74ab215 100644 --- a/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExtensions.cs +++ b/Mono.Debugging/Mono.Debugging.Evaluation/NRefactoryExtensions.cs @@ -25,8 +25,9 @@ using System; using System.Collections.Generic; - -using ICSharpCode.NRefactory.CSharp; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Mono.Debugging.Evaluation { @@ -34,7 +35,7 @@ namespace Mono.Debugging.Evaluation { #region AstType - public static object Resolve (this AstType type, EvaluationContext ctx) + public static object Resolve (this TypeSyntax type, EvaluationContext ctx) { var args = new List (); var name = type.Resolve (ctx, args); @@ -51,16 +52,22 @@ namespace Mono.Debugging.Evaluation return ctx.Adapter.GetType (ctx, name); } - static string Resolve (this AstType type, EvaluationContext ctx, List args) + static string Resolve (this ExpressionSyntax type, EvaluationContext ctx, List args) { - if (type is PrimitiveType) - return Resolve ((PrimitiveType) type, ctx, args); - else if (type is ComposedType) - return Resolve ((ComposedType) type, ctx, args); - else if (type is MemberType) - return Resolve ((MemberType) type, ctx, args); - else if (type is SimpleType) - return Resolve ((SimpleType) type, ctx, args); + if (type is PredefinedTypeSyntax) + return Resolve ((PredefinedTypeSyntax) type, ctx, args); + else if (type is PointerTypeSyntax) + return Resolve ((PointerTypeSyntax)type, ctx, args); + else if (type is NullableTypeSyntax) + return Resolve ((NullableTypeSyntax)type, ctx, args); + else if (type is RefTypeSyntax) + return Resolve ((RefTypeSyntax)type, ctx, args); + else if (type is QualifiedNameSyntax) + return Resolve ((QualifiedNameSyntax) type, ctx, args); + else if (type is IdentifierNameSyntax) + return Resolve ((IdentifierNameSyntax)type, ctx, args); + else if (type is GenericNameSyntax) + return Resolve ((GenericNameSyntax)type, ctx, args); return null; } @@ -69,50 +76,41 @@ namespace Mono.Debugging.Evaluation #region ComposedType - static string Resolve (this ComposedType type, EvaluationContext ctx, List args) + static string Resolve (this PointerTypeSyntax type, EvaluationContext ctx, List args) { - string name; - - if (type.HasNullableSpecifier) { - args.Insert (0, type.BaseType.Resolve (ctx)); - name = "System.Nullable`1"; - } else { - name = type.BaseType.Resolve (ctx, args); - } - - if (type.PointerRank > 0) - name += new string ('*', type.PointerRank); + return type.ElementType.Resolve (ctx, args) + "*"; + } - if (type.ArraySpecifiers.Count > 0) { - foreach (var spec in type.ArraySpecifiers) { - if (spec.Dimensions > 1) - name += "[" + new string (',', spec.Dimensions - 1) + "]"; - else - name += "[]"; - } - } + static string Resolve (this RefTypeSyntax type, EvaluationContext ctx, List args) + { + return type.Type.Resolve (ctx, args); + } - return name; + static string Resolve (this NullableTypeSyntax type, EvaluationContext ctx, List args) + { + args.Insert (0, type.ElementType.Resolve (ctx)); + return "System.Nullable`1"; } - + #endregion ComposedType #region MemberType - static string Resolve (this MemberType type, EvaluationContext ctx, List args) + static string Resolve (this QualifiedNameSyntax type, EvaluationContext ctx, List args) { string name; - if (!type.IsDoubleColon) { - var parent = type.Target.Resolve (ctx, args); - name = parent + "." + type.MemberName; + if (!(type.Left is AliasQualifiedNameSyntax)) { + var parent = type.Left.Resolve (ctx, args); + name = parent + "." + type.Right.Identifier.ValueText; } else { - name = type.MemberName; + name = type.Right.Identifier.ValueText; } - if (type.TypeArguments.Count > 0) { - name += "`" + type.TypeArguments.Count; - foreach (var arg in type.TypeArguments) { + + if (type.Right is GenericNameSyntax genericName) { + name += "`" + genericName.TypeArgumentList.Arguments.Count; + foreach (var arg in genericName.TypeArgumentList.Arguments) { object resolved; if ((resolved = arg.Resolve (ctx)) == null) @@ -129,30 +127,30 @@ namespace Mono.Debugging.Evaluation #region PrimitiveType - public static string Resolve (this PrimitiveType type) + public static string Resolve (this PredefinedTypeSyntax type) { - switch (type.Keyword) { - case "bool": return "System.Boolean"; - case "sbyte": return "System.SByte"; - case "byte": return "System.Byte"; - case "char": return "System.Char"; - case "short": return "System.Int16"; - case "ushort": return "System.UInt16"; - case "int": return "System.Int32"; - case "uint": return "System.UInt32"; - case "long": return "System.Int64"; - case "ulong": return "System.UInt64"; - case "float": return "System.Single"; - case "double": return "System.Double"; - case "decimal": return "System.Decimal"; - case "string": return "System.String"; - case "object": return "System.Object"; - case "void": return "System.Void"; + switch (type.Keyword.Kind()) { + case SyntaxKind.BoolKeyword: return "System.Boolean"; + case SyntaxKind.SByteKeyword: return "System.SByte"; + case SyntaxKind.ByteKeyword: return "System.Byte"; + case SyntaxKind.CharKeyword: return "System.Char"; + case SyntaxKind.ShortKeyword: return "System.Int16"; + case SyntaxKind.UShortKeyword: return "System.UInt16"; + case SyntaxKind.IntKeyword: return "System.Int32"; + case SyntaxKind.UIntKeyword: return "System.UInt32"; + case SyntaxKind.LongKeyword: return "System.Int64"; + case SyntaxKind.ULongKeyword: return "System.UInt64"; + case SyntaxKind.FloatKeyword: return "System.Single"; + case SyntaxKind.DoubleKeyword: return "System.Double"; + case SyntaxKind.DecimalKeyword: return "System.Decimal"; + case SyntaxKind.StringKeyword: return "System.String"; + case SyntaxKind.ObjectKeyword: return "System.Object"; + case SyntaxKind.VoidKeyword: return "System.Void"; default: return null; } } - static string Resolve (this PrimitiveType type, EvaluationContext ctx, List args) + static string Resolve (this PredefinedTypeSyntax type, EvaluationContext ctx, List args) { return Resolve (type); } @@ -161,13 +159,13 @@ namespace Mono.Debugging.Evaluation #region SimpleType - static string Resolve (this SimpleType type, EvaluationContext ctx, List args) + static string Resolve (this GenericNameSyntax type, EvaluationContext ctx, List args) { - string name = type.Identifier; + string name = type.Identifier.ValueText; - if (type.TypeArguments.Count > 0) { - name += "`" + type.TypeArguments.Count; - foreach (var arg in type.TypeArguments) { + if (type.TypeArgumentList.Arguments.Count > 0) { + name += "`" + type.TypeArgumentList.Arguments.Count; + foreach (var arg in type.TypeArgumentList.Arguments) { object resolved; if ((resolved = arg.Resolve (ctx)) == null) @@ -177,7 +175,12 @@ namespace Mono.Debugging.Evaluation } } - return name; + return type.Identifier.ValueText; + } + + static string Resolve (this IdentifierNameSyntax type, EvaluationContext ctx, List args) + { + return type.Identifier.ValueText; } #endregion SimpleType diff --git a/Mono.Debugging/Mono.Debugging.csproj b/Mono.Debugging/Mono.Debugging.csproj index d5f261b..7f40081 100644 --- a/Mono.Debugging/Mono.Debugging.csproj +++ b/Mono.Debugging/Mono.Debugging.csproj @@ -16,14 +16,10 @@ - - - - - + -- cgit v1.2.3