public Resolve ( AstNode node ) : ResolveResult | ||
node | AstNode | |
Résultat | ResolveResult |
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { var mgr = ctx.Resolve (identifierExpression) as MethodGroupResolveResult; if (mgr != null) UsedMethods.AddRange (mgr.Methods); base.VisitIdentifierExpression(identifierExpression); }
protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName) { var typeDecl = node.GetParent <TypeDeclaration>(); if (typeDecl == null) { return(false); } var entityDecl = node.GetParent <EntityDeclaration>(); var memberResolveResult = ctx.Resolve(entityDecl) as MemberResolveResult; if (memberResolveResult == null) { return(false); } var typeResolveResult = ctx.Resolve(typeDecl) as TypeResolveResult; if (typeResolveResult == null) { return(false); } var sourceMember = memberResolveResult.Member; return(typeResolveResult.Type.GetMembers(m => m.Name == variableName).Any(m2 => IsAccessible(sourceMember, m2))); }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { if (startLocation.IsEmpty || startLocation <= identifierExpression.StartLocation && identifierExpression.EndLocation <= endLocation) { SetState(context.Resolve(identifierExpression), VariableState.Used); } }
Func <Expression, bool> GetChecker(Expression expression, IList <IdentifierExpression> identifiers) { // TODO: This only works for simple cases. IList <IMember> members; IList <IVariable> locals; var identifierResolveResults = identifiers.Select(identifier => context.Resolve(identifier)).ToList(); SplitResolveResults(identifierResolveResults, out members, out locals); if (expression is InvocationExpression || expression is ObjectCreateExpression) { return(node => { if (node is InvocationExpression || node is ObjectCreateExpression) { // We don't know what these might do, so assume it will change the initializer return true; } var binaryOperator = node as BinaryOperatorExpression; if (binaryOperator != null) { var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult; if (resolveResult == null) { return false; } // Built-in operators are ok, user defined ones not so much return resolveResult.UserDefinedOperatorMethod != null; } return IsConflictingAssignment(node, identifiers, members, locals); }); } else if (expression is IdentifierExpression) { var initializerDependsOnMembers = identifierResolveResults.Any(result => result is MemberResolveResult); var initializerDependsOnReferenceType = identifierResolveResults.Any(result => result.Type.IsReferenceType == true); return(node => { if ((node is InvocationExpression || node is ObjectCreateExpression) && (initializerDependsOnMembers || initializerDependsOnReferenceType)) { // Anything can happen... return true; } var binaryOperator = node as BinaryOperatorExpression; if (binaryOperator != null) { var resolveResult = context.Resolve(binaryOperator) as OperatorResolveResult; if (resolveResult == null) { return false; } return resolveResult.UserDefinedOperatorMethod != null; } return IsConflictingAssignment(node, identifiers, members, locals); }); } return(node => false); }
void HandlePotentialWrite(Expression expression) { var variableResolveResult = ctx.Resolve(expression) as LocalResolveResult; if (variableResolveResult == null) { return; } variableWritten |= variableResolveResult.Equals(parameter); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression(memberReferenceExpression); var targetMember = context.Resolve(memberReferenceExpression) as MemberResolveResult; if (targetMember != null && targetMember.IsVirtualCall && targetMember.TargetResult is ThisResolveResult) { CreateIssue(memberReferenceExpression); } }
public override void VisitIdentifierExpression(IdentifierExpression identifierExpression) { if (!IsTargetOfInvocation(identifierExpression)) { var mgr = ctx.Resolve(identifierExpression) as MethodGroupResolveResult; if (mgr != null) { UsedMethods.AddRange(mgr.Methods); } } base.VisitIdentifierExpression(identifierExpression); }
bool CheckExceptionType(ObjectCreateExpression objectCreateExpression, out Expression paramNode, out Expression altParam, out bool canAddParameterName) { paramNode = null; altParam = null; canAddParameterName = false; var rr = context.Resolve(objectCreateExpression.Type) as TypeResolveResult; if (rr == null) { return(false); } var type = rr.Type; if (type.Name == typeof(ArgumentException).Name && type.Namespace == typeof(ArgumentException).Namespace) { if (objectCreateExpression.Arguments.Count >= 2) { altParam = objectCreateExpression.Arguments.ElementAt(0); paramNode = objectCreateExpression.Arguments.ElementAt(1); } return(paramNode != null); } if (type.Name == typeof(ArgumentNullException).Name && type.Namespace == typeof(ArgumentNullException).Namespace || type.Name == typeof(ArgumentOutOfRangeException).Name && type.Namespace == typeof(ArgumentOutOfRangeException).Namespace || type.Name == typeof(DuplicateWaitObjectException).Name && type.Namespace == typeof(DuplicateWaitObjectException).Namespace) { canAddParameterName = objectCreateExpression.Arguments.Count == 1; if (objectCreateExpression.Arguments.Count >= 1) { paramNode = objectCreateExpression.Arguments.FirstOrDefault(); if (objectCreateExpression.Arguments.Count == 2) { altParam = objectCreateExpression.Arguments.ElementAt(1); if (!context.Resolve(altParam).Type.IsKnownType(KnownTypeCode.String)) { paramNode = null; } } if (objectCreateExpression.Arguments.Count == 3) { altParam = objectCreateExpression.Arguments.ElementAt(2); } } return(paramNode != null); } return(false); }
static CodeAction CreateAction(BaseRefactoringContext context, Match match, bool negateMatch, BinaryOperatorExpression node) { var target = match.Get <Expression>("target").Single(); var expr = match.Get <Expression>("expr").Single(); if (!expr.DescendantsAndSelf.All(x => !(x is BinaryOperatorExpression) || ((BinaryOperatorExpression)x).Operator == BinaryOperatorType.BitwiseOr) && !expr.DescendantsAndSelf.All(x => !(x is BinaryOperatorExpression) || ((BinaryOperatorExpression)x).Operator == BinaryOperatorType.BitwiseAnd)) { return(null); } var rr = context.Resolve(target); if (rr.Type.Kind != ICSharpCode.NRefactory.TypeSystem.TypeKind.Enum) { return(null); } return(new CodeAction( context.TranslateString("Replace with 'Enum.HasFlag'"), script => { Expression newExpr = BuildHasFlagExpression(target, expr); if (negateMatch) { newExpr = new UnaryOperatorExpression(UnaryOperatorType.Not, newExpr); } script.Replace(node, newExpr); }, node.OperatorToken)); }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); if (!IsCallDependentOnCurrentInstance(invocationExpression)) { // Call within current class scope without 'this' or 'base' return; } var targetMethod = context.Resolve(invocationExpression) as InvocationResolveResult; if (targetMethod == null) { return; } if (targetMethod.IsVirtualCall) { if (targetMethod.Member.DeclaringType.Kind == ICSharpCode.NRefactory.TypeSystem.TypeKind.Delegate) { return; } AddIssue(new CodeIssue(invocationExpression, context.TranslateString("Virtual member call in constructor"), new CodeAction(string.Format(context.TranslateString("Make class '{0}' sealed"), CurrentType.Name), script => script.ChangeModifier(CurrentType, CurrentType.Modifiers | Modifiers.Sealed), invocationExpression))); } }
internal static IType GetRequestedReturnType(BaseRefactoringContext ctx, AstNode returnStatement, out AstNode entityNode) { entityNode = returnStatement.GetParent(p => p is LambdaExpression || p is AnonymousMethodExpression || !(p is Accessor) && p is EntityDeclaration); if (entityNode == null) { return(null); } if (entityNode is EntityDeclaration) { var rr = ctx.Resolve(entityNode) as MemberResolveResult; if (rr == null) { return(null); } return(rr.Member.ReturnType); } foreach (var type in TypeGuessing.GetValidTypes(ctx.Resolver, entityNode)) { if (type.Kind != TypeKind.Delegate) { continue; } var invoke = type.GetDelegateInvokeMethod(); if (invoke != null && !invoke.ReturnType.IsKnownType(KnownTypeCode.Void)) { return(invoke.ReturnType); } } return(null); }
public static bool LambdaTypeCanBeInferred(BaseRefactoringContext ctx, Expression expression, List <ParameterDeclaration> parameters) { var validTypes = TypeGuessing.GetValidTypes(ctx.Resolver, expression).ToList(); foreach (var type in validTypes) { if (type.Kind != TypeKind.Delegate) { continue; } var invokeMethod = type.GetDelegateInvokeMethod(); if (invokeMethod == null || invokeMethod.Parameters.Count != parameters.Count) { continue; } for (int p = 0; p < invokeMethod.Parameters.Count; p++) { var resolvedArgument = ctx.Resolve(parameters[p].Type); if (!invokeMethod.Parameters [p].Type.Equals(resolvedArgument.Type)) { return(false); } } } return(true); }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); var invocationResolveResult = context.Resolve(invocationExpression) as CSharpInvocationResolveResult; if (invocationResolveResult == null) { return; } Expression formatArgument; IList <Expression> formatArguments; TextLocation formatStart; if (!FormatStringHelper.TryGetFormattingParameters(invocationResolveResult, invocationExpression, out formatArgument, out formatStart, out formatArguments, null)) { return; } var primitiveArgument = formatArgument as PrimitiveExpression; if (primitiveArgument == null || !(primitiveArgument.Value is String)) { return; } var format = (string)primitiveArgument.Value; var parsingResult = context.ParseFormatString(format); CheckSegments(parsingResult.Segments, formatStart, formatArguments, invocationExpression); }
public UsingInfo(AstNode node, BaseRefactoringContext context) { var importAndAlias = GetImportAndAlias(node); Node = node; Alias = importAndAlias.Item2; Name = importAndAlias.Item1.ToString(); IsAlias = Alias != null; ResolveResult rr; if (node.Ancestors.Contains(context.RootNode)) { rr = context.Resolve(importAndAlias.Item1); } else { // It's possible that we're looking at a new using that // isn't part of the AST. var resolver = new CSharpAstResolver(new CSharpResolver(context.Compilation), node); rr = resolver.Resolve(importAndAlias.Item1); } var nrr = rr as NamespaceResolveResult; HasTypesFromOtherAssemblies = nrr != null && nrr.Namespace.ContributingAssemblies.Any(a => !a.IsMainAssembly); IsSystem = HasTypesFromOtherAssemblies && (Name == "System" || Name.StartsWith("System.", StringComparison.Ordinal)); }
internal static Expression GetSwitchExpression(BaseRefactoringContext context, Expression expr) { var binaryOp = expr as BinaryOperatorExpression; if (binaryOp == null) { return(null); } if (binaryOp.Operator == BinaryOperatorType.ConditionalOr) { return(GetSwitchExpression(context, binaryOp.Left)); } if (binaryOp.Operator == BinaryOperatorType.Equality) { Expression switchExpr = null; if (IsConstantExpression(context, binaryOp.Right)) { switchExpr = binaryOp.Left; } if (IsConstantExpression(context, binaryOp.Left)) { switchExpr = binaryOp.Right; } if (switchExpr != null && IsValidSwitchType(context.Resolve(switchExpr).Type)) { return(switchExpr); } } return(null); }
internal static IField ScanSetter(BaseRefactoringContext context, PropertyDeclaration propertyDeclaration) { if (propertyDeclaration.Setter.Body.Statements.Count != 1) { return(null); } var setAssignment = propertyDeclaration.Setter.Body.Statements.First() as ExpressionStatement; var assignment = setAssignment != null ? setAssignment.Expression as AssignmentExpression : null; if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign) { return(null); } var idExpr = assignment.Right as IdentifierExpression; if (idExpr == null || idExpr.Identifier != "value") { return(null); } if (!IsPossibleExpression(assignment.Left)) { return(null); } var result = context.Resolve(assignment.Left); if (result == null || !(result is MemberResolveResult)) { return(null); } return(((MemberResolveResult)result).Member as IField); }
static bool IsConstantExpression(BaseRefactoringContext context, Expression expr) { if (expr is PrimitiveExpression || expr is NullReferenceExpression) { return(true); } return(context.Resolve(expr).IsCompileTimeConstant); }
protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName) { var typeDecl = node.GetParent<TypeDeclaration>(); if (typeDecl == null) return false; var entityDecl = node.GetParent<EntityDeclaration>(); var memberResolveResult = ctx.Resolve(entityDecl) as MemberResolveResult; if (memberResolveResult == null) return false; var typeResolveResult = ctx.Resolve(typeDecl) as TypeResolveResult; if (typeResolveResult == null) return false; var sourceMember = memberResolveResult.Member; return typeResolveResult.Type.GetMembers(m => m.Name == variableName).Any(m2 => IsAccessible(sourceMember, m2)); }
public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) { base.VisitMemberReferenceExpression(memberReferenceExpression); if (memberReferenceExpression == null || memberReferenceExpression.Target is ThisReferenceExpression) { // Call within current class scope using 'this' or 'base' return; } var memberResolveResult = context.Resolve(memberReferenceExpression) as MemberResolveResult; if (memberResolveResult == null) { return; } if (!memberResolveResult.Member.IsStatic) { return; } HandleMember(memberReferenceExpression, memberReferenceExpression.Target, memberResolveResult.Member, memberResolveResult.TargetResult); }
protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName, out IMember member) { MemberCollectionService mcs = (MemberCollectionService)ctx.GetService(typeof(MemberCollectionService)); if (mcs == null) { lock (ctx) { if ((mcs = (MemberCollectionService)ctx.GetService(typeof(MemberCollectionService))) == null) { mcs = new MemberCollectionService(); ctx.Services.AddService(typeof(MemberCollectionService), mcs); } } } var typeDecl = node.GetParent <TypeDeclaration>(); member = null; if (typeDecl == null) { return(false); } var entityDecl = node.GetParent <EntityDeclaration>(); var memberResolveResult = ctx.Resolve(entityDecl) as MemberResolveResult; if (memberResolveResult == null) { return(false); } var typeResolveResult = ctx.Resolve(typeDecl) as TypeResolveResult; if (typeResolveResult == null) { return(false); } var sourceMember = memberResolveResult.Member; member = mcs.GetMembers(typeResolveResult.Type, variableName).FirstOrDefault(m2 => IsAccessible(sourceMember, m2)); return(member != null); }
protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName) { var typeDecl = node.GetParent<TypeDeclaration> (); if (typeDecl == null) return false; var typeResolveResult = ctx.Resolve (typeDecl) as TypeResolveResult; if (typeResolveResult == null) return false; var entityDecl = node.GetParent<EntityDeclaration> (); var isStatic = (entityDecl.Modifiers & Modifiers.Static) == Modifiers.Static; return typeResolveResult.Type.GetMembers (m => m.Name == variableName && m.IsStatic == isStatic).Any (); }
static void ExecuteScriptToFixStaticMethodIssue(Script script, BaseRefactoringContext context, AstNode methodDeclaration) { var clonedDeclaration = (MethodDeclaration)methodDeclaration.Clone(); clonedDeclaration.Modifiers |= Modifiers.Static; script.Replace(methodDeclaration, clonedDeclaration); var rr = context.Resolve(methodDeclaration) as MemberResolveResult; //var method = (IMethod)rr.Member; //method.ImplementedInterfaceMembers.Any(m => methodGroupResolveResult.Methods.Contains((IMethod)m)); /*script.DoGlobalOperationOn(rr.Member, * (fctx, fscript, fnode) => { * DoStaticMethodGlobalOperation(fnode, fctx, rr, fscript); });*/ }
internal static IType GetRequestedReturnType(BaseRefactoringContext ctx, AstNode returnStatement, out AstNode entityNode) { entityNode = returnStatement.GetParent(p => p is LambdaExpression || p is AnonymousMethodExpression || !(p is Accessor) && p is EntityDeclaration); if (entityNode == null) { return(SpecialType.UnknownType); } if (entityNode is EntityDeclaration) { var rr = ctx.Resolve(entityNode) as MemberResolveResult; if (rr == null) { return(SpecialType.UnknownType); } if (((EntityDeclaration)entityNode).HasModifier(Modifiers.Async)) { return(TaskType.UnpackTask(ctx.Compilation, rr.Member.ReturnType)); } return(rr.Member.ReturnType); } bool isAsync = false; if (entityNode is LambdaExpression) { isAsync = ((LambdaExpression)entityNode).IsAsync; } if (entityNode is AnonymousMethodExpression) { isAsync = ((AnonymousMethodExpression)entityNode).IsAsync; } foreach (var type in TypeGuessing.GetValidTypes(ctx.Resolver, entityNode)) { if (type.Kind != TypeKind.Delegate) { continue; } var invoke = type.GetDelegateInvokeMethod(); if (invoke != null) { return(isAsync ? TaskType.UnpackTask(ctx.Compilation, invoke.ReturnType) : invoke.ReturnType); } } return(SpecialType.UnknownType); }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); // Speed up the inspector by discarding some invocations early var hasEligibleArgument = invocationExpression.Arguments.Any(argument => { var primitiveArg = argument as PrimitiveExpression; return(primitiveArg != null && primitiveArg.Value is string); }); if (!hasEligibleArgument) { return; } var invocationResolveResult = context.Resolve(invocationExpression) as CSharpInvocationResolveResult; if (invocationResolveResult == null) { return; } Expression formatArgument; IList <Expression> formatArguments; TextLocation formatStart; if (!FormatStringHelper.TryGetFormattingParameters(invocationResolveResult, invocationExpression, out formatArgument, out formatStart, out formatArguments, null)) { return; } var primitiveArgument = formatArgument as PrimitiveExpression; if (primitiveArgument == null || !(primitiveArgument.Value is string)) { return; } var format = (string)primitiveArgument.Value; var parsingResult = context.ParseFormatString(format); CheckSegments(parsingResult.Segments, formatStart, formatArguments, invocationExpression); }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); if (!IsCallDependentOnCurrentInstance(invocationExpression)) { // Call within current class scope without 'this' or 'base' return; } var targetMethod = context.Resolve(invocationExpression) as InvocationResolveResult; if (targetMethod == null) { return; } if (targetMethod.IsVirtualCall) { AddIssue(invocationExpression, context.TranslateString("Constructors should not call virtual members")); } }
protected static bool HidesMember(BaseRefactoringContext ctx, AstNode node, string variableName) { var typeDecl = node.GetParent <TypeDeclaration> (); if (typeDecl == null) { return(false); } var typeResolveResult = ctx.Resolve(typeDecl) as TypeResolveResult; if (typeResolveResult == null) { return(false); } var entityDecl = node.GetParent <EntityDeclaration> (); var isStatic = (entityDecl.Modifiers & Modifiers.Static) == Modifiers.Static; return(typeResolveResult.Type.GetMembers(m => m.Name == variableName && m.IsStatic == isStatic).Any()); }
bool IsSafeExpression(Expression expression, BaseRefactoringContext context) { var components = expression.DescendantsAndSelf; foreach (var c in components) { if (c is AssignmentExpression) { return(false); } else if (c is UnaryOperatorExpression) { var ope = ((UnaryOperatorExpression)c).Operator; if (ope == UnaryOperatorType.Decrement || ope == UnaryOperatorType.Increment || ope == UnaryOperatorType.PostDecrement || ope == UnaryOperatorType.PostIncrement) { return(false); } } else if (c is IdentifierExpression) { var result = context.Resolve(c); if (result.IsError) { return(false); } if (!(result is LocalResolveResult)) { return(false); } if ((((LocalResolveResult)result).IsParameter)) { return(false); } } } return(true); }
public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) { var parameters = objectCreateExpression.Arguments; if (parameters.Count != 2) { return; } var firstParam = parameters.FirstOrNullObject() as PrimitiveExpression; var secondParam = parameters.LastOrNullObject() as PrimitiveExpression; if (firstParam == null || !(firstParam.Value is string) || secondParam == null || !(secondParam.Value is string)) { return; } var type = context.Resolve(objectCreateExpression.Type) as TypeResolveResult; if (type == null) { return; } var leftLength = (firstParam.Value as string).Length; var rightLength = (secondParam.Value as string).Length; Func <int, int, bool> func; if (!rules.TryGetValue(type.Type.FullName, out func)) { return; } if (!func(leftLength, rightLength)) { AddIssue(objectCreateExpression, context.TranslateString("The parameters are in the wrong order"), GetActions(objectCreateExpression, firstParam, secondParam)); } }
internal static IField ScanGetter(BaseRefactoringContext context, PropertyDeclaration propertyDeclaration) { if (propertyDeclaration.Getter.Body.Statements.Count != 1) { return(null); } var returnStatement = propertyDeclaration.Getter.Body.Statements.First() as ReturnStatement; if (returnStatement == null) { return(null); } if (!IsPossibleExpression(returnStatement.Expression)) { return(null); } var result = context.Resolve(returnStatement.Expression); if (result == null || !(result is MemberResolveResult)) { return(null); } return(((MemberResolveResult)result).Member as IField); }
public static IType GuessType(BaseRefactoringContext context, AstNode expr) { if (expr is SimpleType && expr.Role == Roles.TypeArgument) { if (expr.Parent is MemberReferenceExpression || expr.Parent is IdentifierExpression) { var rr = context.Resolve (expr.Parent); var argumentNumber = expr.Parent.GetChildrenByRole (Roles.TypeArgument).TakeWhile (c => c != expr).Count (); var mgrr = rr as MethodGroupResolveResult; if (mgrr != null && mgrr.Methods.Any () && mgrr.Methods.First ().TypeArguments.Count > argumentNumber) return mgrr.Methods.First ().TypeParameters[argumentNumber]; } else if (expr.Parent is MemberType || expr.Parent is SimpleType) { var rr = context.Resolve (expr.Parent); var argumentNumber = expr.Parent.GetChildrenByRole (Roles.TypeArgument).TakeWhile (c => c != expr).Count (); var mgrr = rr as TypeResolveResult; if (mgrr != null && mgrr.Type.TypeParameterCount > argumentNumber) { return mgrr.Type.GetDefinition ().TypeParameters[argumentNumber]; } } } var type = GetValidTypes(context.Resolver, expr).ToArray(); var typeInference = new TypeInference(context.Compilation); typeInference.Algorithm = TypeInferenceAlgorithm.Improved; var inferedType = typeInference.FindTypeInBounds(type, emptyTypes); return inferedType; }
public override IEnumerable<CodeIssue> GetIssues(BaseRefactoringContext context, string subIssue = null) { foreach (var mre in context.RootNode.Descendants.OfType<MemberReferenceExpression>()) { var rr = context.Resolve(mre); var mrr = rr as MemberResolveResult; if (mrr == null) continue; switch (mrr.Member.FullName) { case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainWin32Window": yield return Issue( mre, script => { script.Replace(mre, new IdentifierExpression("SD").Member("WinForms").Member("MainWin32Window")); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.Workbench": yield return Issue( mre, script => { script.Replace(mre, new IdentifierExpression("SD").Member("Workbench")); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.StatusBar": yield return Issue( mre, script => { script.Replace(mre, new IdentifierExpression("SD").Member("StatusBar")); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.InvokeRequired": yield return Issue( mre, script => { script.Replace(mre, new IdentifierExpression("SD").Member("MainThread").Member("InvokeRequired")); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.MainWindow": yield return Issue( mre, script => { script.Replace(mre, new IdentifierExpression("SD").Member("Workbench").Member("MainWindow")); }); break; } } foreach (var invocationExpression in context.RootNode.Descendants.OfType<InvocationExpression>()) { var rr = context.Resolve(invocationExpression); var irr = rr as CSharpInvocationResolveResult; if (irr == null) continue; switch (irr.Member.FullName) { case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.CallLater": yield return Issue( invocationExpression, script => { script.Replace(invocationExpression, new IdentifierExpression("SD").Member("MainThread").Invoke("CallLater", invocationExpression.Arguments.Select(e => e.Clone()))); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.AssertMainThread": yield return Issue( invocationExpression, script => { script.Replace(invocationExpression, new IdentifierExpression("SD").Member("MainThread").Invoke("VerifyAccess")); }); break; case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.SafeThreadAsyncCall": { // SD.MainThread.InvokeAsync(argument).FireAndForget(); Expression arg = invocationExpression.Arguments.First().Clone(); if (invocationExpression.Arguments.Count > 1) arg = new LambdaExpression { Body = arg.Invoke(invocationExpression.Arguments.Skip(1).Select(a => a.Clone())) }; yield return Issue( invocationExpression, script => { script.Replace(invocationExpression, new IdentifierExpression("SD").Member("MainThread") .Invoke("InvokeAsyncAndForget", arg)); }); break; } case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.SafeThreadCall": case "ICSharpCode.SharpDevelop.Gui.WorkbenchSingleton.SafeThreadFunction": { // SD.MainThread.InvokeIfRequired(argument); Expression arg = invocationExpression.Arguments.First().Clone(); if (invocationExpression.Arguments.Count > 1) arg = new LambdaExpression { Body = arg.Invoke(invocationExpression.Arguments.Skip(1).Select(a => a.Clone())) }; yield return Issue( invocationExpression, script => { script.Replace(invocationExpression, new IdentifierExpression("SD").Member("MainThread").Invoke("InvokeIfRequired", arg)); }); break; } case "ICSharpCode.SharpDevelop.IMessageLoop.InvokeAsync": // We used to recommend SD.MainThread.InvokeAsync(...).FireAndForget(), // but it's better to use SD.MainThread.InvokeAsyncAndForget(...) if (invocationExpression.Clone().Invoke("FireAndForget").IsMatch(invocationExpression.Parent.Parent)) { var ident = invocationExpression.Parent.GetChildByRole(Roles.Identifier); yield return new CodeIssue( ident.StartLocation, ident.EndLocation, "Use InvokeAsyncAndForget() instead", new CodeAction("Use InvokeAsyncAndForget() instead", script => { var newInvocation = (InvocationExpression)invocationExpression.Clone(); ((MemberReferenceExpression)newInvocation.Target).MemberName = "InvokeAsyncAndForget"; script.Replace(invocationExpression.Parent.Parent, newInvocation); }, ident)); } break; } } }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); // Speed up the inspector by discarding some invocations early var hasEligibleArgument = invocationExpression.Arguments.Any(argument => { var primitiveArg = argument as PrimitiveExpression; return(primitiveArg != null && primitiveArg.Value is string); }); if (!hasEligibleArgument) { return; } var invocationResolveResult = context.Resolve(invocationExpression) as CSharpInvocationResolveResult; if (invocationResolveResult == null) { return; } Expression formatArgument; IList <Expression> formatArguments; if (!FormatStringHelper.TryGetFormattingParameters(invocationResolveResult, invocationExpression, out formatArgument, out formatArguments, null)) { return; } var primitiveArgument = formatArgument as PrimitiveExpression; if (primitiveArgument == null || !(primitiveArgument.Value is string)) { return; } var format = (string)primitiveArgument.Value; var parsingResult = context.ParseFormatString(format); CheckSegments(parsingResult.Segments, formatArgument.StartLocation, formatArguments, invocationExpression); var argUsed = new HashSet <int> (); foreach (var item in parsingResult.Segments) { var fi = item as FormatItem; if (fi == null) { continue; } argUsed.Add(fi.Index); } for (int i = 0; i < formatArguments.Count; i++) { if (!argUsed.Contains(i)) { AddIssue(new CodeIssue(formatArguments[i], ctx.TranslateString("Argument is not used in format string")) { IssueMarker = IssueMarker.GrayOut }); } } }
static IType GetReturnType(BaseRefactoringContext context, AstNode currentFunction) { var resolveResult = context.Resolve(currentFunction); return(resolveResult.IsError ? null : resolveResult.Type); }
internal static IField ScanGetter (BaseRefactoringContext context, PropertyDeclaration propertyDeclaration) { if (propertyDeclaration.Getter.Body.Statements.Count != 1) return null; var returnStatement = propertyDeclaration.Getter.Body.Statements.First () as ReturnStatement; if (returnStatement == null) return null; if (!IsPossibleExpression(returnStatement.Expression)) return null; var result = context.Resolve (returnStatement.Expression); if (result == null || !(result is MemberResolveResult)) return null; return ((MemberResolveResult)result).Member as IField; }
static CodeAction HandleNegatedCase(BaseRefactoringContext ctx, IfElseStatement ifElseStatement, Match match, out IsExpression isExpression, out int foundCastCount) { foundCastCount = 0; var outerIs = match.Get <Expression>("isExpression").Single(); isExpression = CSharpUtil.GetInnerMostExpression(outerIs) as IsExpression; var obj = CSharpUtil.GetInnerMostExpression(isExpression.Expression); var castToType = isExpression.Type; var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone())) }; var rr = ctx.Resolve(castToType); if (rr == null || rr.IsError || rr.Type.IsReferenceType == false) { return(null); } var foundCasts = ifElseStatement.GetParent <BlockStatement>().DescendantNodes(n => n.StartLocation >= ifElseStatement.StartLocation && !cast.IsMatch(n)).Where(n => cast.IsMatch(n)).ToList(); foundCastCount = foundCasts.Count; return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr.Type), ifElseStatement.StartLocation); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(obj.Clone(), castToType.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression()); var linkedNodes = new List <AstNode>(); linkedNodes.Add(varDec.Variables.First().NameToken); linkedNodes.Add(binaryOperatorIdentifier); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; foreach (var node in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n))) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); node.ReplaceWith(id); } block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(ifElseStatement.Condition, binaryOperatorExpression); foreach (var c in foundCasts) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); script.Replace(c, id); } } script.Link(linkedNodes); }, isExpression.IsToken)); }
internal static IField ScanSetter (BaseRefactoringContext context, PropertyDeclaration propertyDeclaration) { if (propertyDeclaration.Setter.Body.Statements.Count != 1) return null; var setAssignment = propertyDeclaration.Setter.Body.Statements.First () as ExpressionStatement; var assignment = setAssignment != null ? setAssignment.Expression as AssignmentExpression : null; if (assignment == null || assignment.Operator != AssignmentOperatorType.Assign) return null; var idExpr = assignment.Right as IdentifierExpression; if (idExpr == null || idExpr.Identifier != "value") return null; if (!IsPossibleExpression(assignment.Left)) return null; var result = context.Resolve (assignment.Left); if (result == null || !(result is MemberResolveResult)) return null; return ((MemberResolveResult)result).Member as IField; }