This commit is contained in:
mkrueger 2021-05-20 13:34:54 +02:00 коммит произвёл nosami
Родитель f7085b2d81
Коммит 20dce7a122
6 изменённых файлов: 492 добавлений и 1504 удалений

Просмотреть файл

@ -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<string, ValueReference> userVariables;
readonly EvaluationContext ctx;
@ -25,7 +25,7 @@ namespace Mono.Debugging.Evaluation
List<string> definedIdentifier;
int gensymCount;
public LambdaBodyOutputVisitor (EvaluationContext ctx, Dictionary<string, ValueReference> userVariables, TextWriter writer) : base (writer, FormattingOptionsFactory.CreateMono ())
public LambdaBodyOutputVisitor (EvaluationContext ctx, Dictionary<string, ValueReference> userVariables, TextWriter writer)
{
this.ctx = ctx;
this.userVariables = userVariables;
@ -33,12 +33,21 @@ namespace Mono.Debugging.Evaluation
this.definedIdentifier = new List<string> ();
}
void WriteKeyword (string keyword)
{
}
void WriteIdentifier (string keyword)
{
}
public Tuple<string, object>[] GetLocalValues ()
{
var locals = new Tuple<string, object>[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<ValueReference> (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<ValueReference> (visitor);
return visitor.Visit (t);
}
ValueReference Evaluate (ThisReferenceExpression t)
ValueReference Evaluate (ThisExpressionSyntax t)
{
var visitor = new NRefactoryExpressionEvaluatorVisitor (ctx, "this", null, userVariables);
return t.AcceptVisitor<ValueReference> (visitor);
return visitor.Visit (t);
}
string GenerateSymbol (string s)
@ -141,14 +150,14 @@ namespace Mono.Debugging.Evaluation
string GetLocalName (string name)
{
Tuple<string, object> 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);
}
/*
public override void VisitMemberReferenceExpression (MemberReferenceExpression memberReferenceExpression)
{
}*/
public override void VisitNamedArgumentExpression (NamedArgumentExpression namedArgumentExpression)
{
throw NotSupportedToConsistency ();
WriteIdentifier (")");
}
public override void VisitNamedExpression (NamedExpression namedExpression)
public override void VisitSimpleLambdaExpression (SimpleLambdaExpressionSyntax node)
{
throw NotSupportedToConsistency ();
}
/*
public override void VisitNullReferenceExpression (NullReferenceExpression nullReferenceExpression)
{
}
*//*
public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
{
}*/
if (node.Parameter.Modifiers.Count > 0)
throw NotSupported ();
public override void VisitAnonymousTypeCreateExpression (AnonymousTypeCreateExpression anonymousTypeCreateExpression)
{
throw NotSupportedToConsistency ();
}
/*
public override void VisitParenthesizedExpression (ParenthesizedExpression parenthesizedExpression)
{
}*/
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 ();
definedIdentifier.Add (node.Parameter.Identifier.ValueText);
Visit (node.Body);
}
public override void VisitStackAllocExpression (StackAllocExpression stackAllocExpression)
public override void VisitThisExpression (ThisExpressionSyntax node)
{
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)
public override void VisitParameter (ParameterSyntax node)
{
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)
{
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)
public override void DefaultVisit (SyntaxNode node)
{
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)
{
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
}
}

Просмотреть файл

@ -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<string>". 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);
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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<Replacement> replacements = new List<Replacement> ();
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);
}
}
}
}

Просмотреть файл

@ -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<object> ();
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<object> args)
static string Resolve (this ExpressionSyntax type, EvaluationContext ctx, List<object> 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<object> args)
static string Resolve (this PointerTypeSyntax type, EvaluationContext ctx, List<object> 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);
if (type.ArraySpecifiers.Count > 0) {
foreach (var spec in type.ArraySpecifiers) {
if (spec.Dimensions > 1)
name += "[" + new string (',', spec.Dimensions - 1) + "]";
else
name += "[]";
}
}
return name;
return type.ElementType.Resolve (ctx, args) + "*";
}
static string Resolve (this RefTypeSyntax type, EvaluationContext ctx, List<object> args)
{
return type.Type.Resolve (ctx, args);
}
static string Resolve (this NullableTypeSyntax type, EvaluationContext ctx, List<object> 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<object> args)
static string Resolve (this QualifiedNameSyntax type, EvaluationContext ctx, List<object> 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<object> args)
static string Resolve (this PredefinedTypeSyntax type, EvaluationContext ctx, List<object> args)
{
return Resolve (type);
}
@ -161,13 +159,13 @@ namespace Mono.Debugging.Evaluation
#region SimpleType
static string Resolve (this SimpleType type, EvaluationContext ctx, List<object> args)
static string Resolve (this GenericNameSyntax type, EvaluationContext ctx, List<object> 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<object> args)
{
return type.Identifier.ValueText;
}
#endregion SimpleType

Просмотреть файл

@ -16,14 +16,10 @@
<Import Project="..\Mono.Debugging.settings" />
<ItemGroup>
<ProjectReference Include="..\..\nrefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj" />
<ProjectReference Include="..\..\nrefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Buffers" Version="4.5.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.8.0" />
</ItemGroup>
</Project>