public ToolTipData (ICSharpCode.NRefactory.PlayScript.SyntaxTree unit, ICSharpCode.NRefactory.Semantics.ResolveResult result, ICSharpCode.NRefactory.PlayScript.AstNode node, CSharpAstResolver file) { this.Unit = unit; this.Result = result; this.Node = node; this.Resolver = file; }
public override IEntity ResolveCref(string cref) { if (cref.Length > 2 && cref[1] == ':') { // resolve ID string return base.ResolveCref(cref); } var documentationReference = new PlayScriptParser().ParseDocumentationReference(cref); var csharpContext = context as CSharpTypeResolveContext; CSharpResolver resolver; if (csharpContext != null) { resolver = new CSharpResolver(csharpContext); } else { resolver = new CSharpResolver(context.Compilation); } var astResolver = new CSharpAstResolver(resolver, documentationReference); var rr = astResolver.Resolve(documentationReference); MemberResolveResult mrr = rr as MemberResolveResult; if (mrr != null) return mrr.Member; TypeResolveResult trr = rr as TypeResolveResult; if (trr != null) return trr.Type.GetDefinition(); return null; }
public static ResolveResult Resolve(Lazy<ICompilation> compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, CancellationToken cancellationToken = default(CancellationToken)) { node = syntaxTree.GetNodeAt(location); if (node == null || node is ArrayInitializerExpression) return null; if (node.Parent is UsingAliasDeclaration && node.Role == UsingAliasDeclaration.AliasRole) { var r = new CSharpAstResolver(compilation.Value, syntaxTree, unresolvedFile); return r.Resolve(((UsingAliasDeclaration)node.Parent).Import, cancellationToken); } if (CSharpAstResolver.IsUnresolvableNode(node)) { if (node is Identifier) { node = node.Parent; } else if (node.NodeType == NodeType.Token) { if (node.Parent is IndexerExpression || node.Parent is ConstructorInitializer) { // There's no other place where one could hover to see the indexer's tooltip, // so we need to resolve it when hovering over the '[' or ']'. // For constructor initializer, the same applies to the 'base'/'this' token. node = node.Parent; } else { return null; } } else { // don't resolve arbitrary nodes - we don't want to show tooltips for everything return null; } } else { // It's a resolvable node. // However, we usually don't want to show the tooltip everywhere // For example, hovering with the mouse over an empty line between two methods causes // node==TypeDeclaration, but we don't want to show any tooltip. if (!node.GetChildByRole(Roles.Identifier).IsNull) { // We'll suppress the tooltip for resolvable nodes if there is an identifier that // could be hovered over instead: return null; } } if (node == null) return null; if (node.Parent is ObjectCreateExpression && node.Role == Roles.Type) { node = node.Parent; } InvocationExpression parentInvocation = null; if ((node is IdentifierExpression || node is MemberReferenceExpression || node is PointerReferenceExpression) && node.Role != Roles.Argument) { // we also need to resolve the invocation parentInvocation = node.Parent as InvocationExpression; } // TODO: I think we should provide an overload so that an existing CSharpAstResolver can be reused CSharpAstResolver resolver = new CSharpAstResolver(compilation.Value, syntaxTree, unresolvedFile); ResolveResult rr = resolver.Resolve(node, cancellationToken); MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult; if (mgrr != null) { // For method groups, resolve the parent invocation instead. if (parentInvocation != null) return resolver.Resolve(parentInvocation); if (node is Expression) { // If it's not an invocation, try if it's a conversion to a delegate type: Conversion c = resolver.GetConversion((Expression)node, cancellationToken); if (c.IsMethodGroupConversion) return new MemberResolveResult(mgrr.TargetResult, c.Method); } } return rr; }
public override TooltipItem GetItem (Mono.TextEditor.TextEditor editor, int offset) { var doc = IdeApp.Workbench.ActiveDocument; if (doc == null || doc.ParsedDocument == null) return null; var unit = doc.ParsedDocument.GetAst<SyntaxTree> (); if (unit == null) return null; var file = doc.ParsedDocument.ParsedFile as CSharpUnresolvedFile; if (file == null) return null; ResolveResult result; AstNode node; var loc = editor.OffsetToLocation (offset); if (!doc.TryResolveAt (loc, out result, out node)) { if (node is CSharpTokenNode) { int startOffset2 = editor.LocationToOffset (node.StartLocation); int endOffset2 = editor.LocationToOffset (node.EndLocation); return new TooltipItem (new ToolTipData (unit, result, node, null), startOffset2, endOffset2 - startOffset2); } return null; } if (node == lastNode) return lastResult; var resolver = new CSharpAstResolver (doc.Compilation, unit, file); resolver.ApplyNavigator (new NodeListResolveVisitorNavigator (node), CancellationToken.None); var hoverNode = node.GetNodeAt (loc) ?? node; int startOffset = editor.LocationToOffset (hoverNode.StartLocation); int endOffset = editor.LocationToOffset (hoverNode.EndLocation); return lastResult = new TooltipItem (new ToolTipData (unit, result, node, resolver), startOffset, endOffset - startOffset); }
public ErrorVisitor (CSharpAstResolver resolver, CancellationToken cancellationToken = default(CancellationToken)) { this.resolver = resolver; this.cancellationToken = cancellationToken; }
internal override void NavigatorDone(CSharpAstResolver resolver, CancellationToken cancellationToken) { foreach (var expr in potentialMethodGroupConversions) { var conversion = resolver.GetConversion(expr, cancellationToken); if (conversion.IsMethodGroupConversion && findReferences.IsMemberMatch(method, conversion.Method, conversion.IsVirtualMethodLookup)) { IType targetType = resolver.GetExpectedType(expr, cancellationToken); ResolveResult result = resolver.Resolve(expr, cancellationToken); ReportMatch(expr, new ConversionResolveResult(targetType, result, conversion)); } } base.NavigatorDone(resolver, cancellationToken); }
/// <summary> /// Finds all references in the given file. /// </summary> /// <param name="searchScopes">The search scopes for which to look.</param> /// <param name="unresolvedFile">The type system representation of the file being searched.</param> /// <param name="syntaxTree">The syntax tree of the file being searched.</param> /// <param name="compilation">The compilation for the project that contains the file.</param> /// <param name="callback">Callback used to report the references that were found.</param> /// <param name="cancellationToken">CancellationToken that may be used to cancel the operation.</param> public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, ICompilation compilation, FoundReferenceCallback callback, CancellationToken cancellationToken) { if (searchScopes == null) throw new ArgumentNullException("searchScopes"); if (syntaxTree == null) throw new ArgumentNullException("syntaxTree"); if (compilation == null) throw new ArgumentNullException("compilation"); if (callback == null) throw new ArgumentNullException("callback"); if (searchScopes.Count == 0) return; var navigators = new IResolveVisitorNavigator[searchScopes.Count]; for (int i = 0; i < navigators.Length; i++) { navigators[i] = searchScopes[i].GetNavigator(compilation, callback); } IResolveVisitorNavigator combinedNavigator; if (searchScopes.Count == 1) { combinedNavigator = navigators[0]; } else { combinedNavigator = new CompositeResolveVisitorNavigator(navigators); } cancellationToken.ThrowIfCancellationRequested(); combinedNavigator = new DetectSkippableNodesNavigator(combinedNavigator, syntaxTree); cancellationToken.ThrowIfCancellationRequested(); CSharpAstResolver resolver = new CSharpAstResolver(compilation, syntaxTree, unresolvedFile); resolver.ApplyNavigator(combinedNavigator, cancellationToken); foreach (var n in navigators) { var frn = n as FindReferenceNavigator; if (frn != null) frn.NavigatorDone(resolver, cancellationToken); } }
bool TypeChangeResolvesCorrectly(ParameterDeclaration parameter, AstNode rootNode, IType type) { MethodResolveCount++; var resolver = ctx.GetResolverStateBefore(rootNode); resolver = resolver.AddVariable(new DefaultParameter(type, parameter.Name)); var astResolver = new CSharpAstResolver(resolver, rootNode, ctx.UnresolvedFile); var validator = new TypeChangeValidationNavigator(); astResolver.ApplyNavigator(validator, ctx.CancellationToken); return !validator.FoundErrors; }
internal static IEnumerable<IType> GetValidTypes(CSharpAstResolver resolver, AstNode expr) { if (expr.Parent is DirectionExpression) { var parent = expr.Parent.Parent; if (parent is InvocationExpression) { var invoke = (InvocationExpression)parent; return GetAllValidTypesFromInvokation(resolver, invoke, expr.Parent); } } if (expr.Parent is ArrayInitializerExpression) { if (expr is NamedExpression) return new [] { resolver.Resolve(((NamedExpression)expr).Expression).Type }; var aex = expr.Parent as ArrayInitializerExpression; if (aex.IsSingleElement) aex = aex.Parent as ArrayInitializerExpression; var type = GetElementType(resolver, resolver.Resolve(aex.Parent).Type); if (type.Kind != TypeKind.Unknown) return new [] { type }; } if (expr.Parent is ObjectCreateExpression) { var invoke = (ObjectCreateExpression)expr.Parent; return GetAllValidTypesFromObjectCreation(resolver, invoke, expr); } if (expr.Parent is ArrayCreateExpression) { var ace = (ArrayCreateExpression)expr.Parent; if (!ace.Type.IsNull) { return new [] { resolver.Resolve(ace.Type).Type }; } } if (expr.Parent is InvocationExpression) { var parent = expr.Parent; if (parent is InvocationExpression) { var invoke = (InvocationExpression)parent; return GetAllValidTypesFromInvokation(resolver, invoke, expr); } } if (expr.Parent is VariableInitializer) { var initializer = (VariableInitializer)expr.Parent; var field = initializer.GetParent<FieldDeclaration>(); if (field != null) return new [] { resolver.Resolve(field.ReturnType).Type }; return new [] { resolver.Resolve(initializer).Type }; } if (expr.Parent is CastExpression) { var cast = (CastExpression)expr.Parent; return new [] { resolver.Resolve(cast.Type).Type }; } if (expr.Parent is AsExpression) { var cast = (AsExpression)expr.Parent; return new [] { resolver.Resolve(cast.Type).Type }; } if (expr.Parent is AssignmentExpression) { var assign = (AssignmentExpression)expr.Parent; var other = assign.Left == expr ? assign.Right : assign.Left; return new [] { resolver.Resolve(other).Type }; } if (expr.Parent is BinaryOperatorExpression) { var assign = (BinaryOperatorExpression)expr.Parent; var other = assign.Left == expr ? assign.Right : assign.Left; return new [] { resolver.Resolve(other).Type }; } if (expr.Parent is ReturnStatement) { var state = resolver.GetResolverStateBefore(expr.Parent); if (state != null && state.CurrentMember != null) return new [] { state.CurrentMember.ReturnType }; } if (expr.Parent is YieldReturnStatement) { var state = resolver.GetResolverStateBefore(expr); if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) { var pt = (ParameterizedType)state.CurrentMember.ReturnType; if (pt.FullName == "System.Collections.Generic.IEnumerable") { return new [] { pt.TypeArguments.First() }; } } } if (expr.Parent is UnaryOperatorExpression) { var uop = (UnaryOperatorExpression)expr.Parent; switch (uop.Operator) { case UnaryOperatorType.Not: return new [] { resolver.Compilation.FindType(KnownTypeCode.Boolean) }; case UnaryOperatorType.Minus: case UnaryOperatorType.Plus: case UnaryOperatorType.Increment: case UnaryOperatorType.Decrement: case UnaryOperatorType.PostIncrement: case UnaryOperatorType.PostDecrement: return new [] { resolver.Compilation.FindType(KnownTypeCode.Int32) }; } } return Enumerable.Empty<IType>(); }
static IType GetElementType(CSharpAstResolver resolver, IType type) { // TODO: A better get element type method. if (type.Kind == TypeKind.Array || type.Kind == TypeKind.Dynamic) { if (type.Kind == TypeKind.Array) return ((ArrayType)type).ElementType; return resolver.Compilation.FindType(KnownTypeCode.Object); } foreach (var method in type.GetMethods (m => m.Name == "GetEnumerator")) { IType returnType = null; foreach (var prop in method.ReturnType.GetProperties(p => p.Name == "Current")) { if (returnType != null && prop.ReturnType.IsKnownType (KnownTypeCode.Object)) continue; returnType = prop.ReturnType; } if (returnType != null) return returnType; } return resolver.Compilation.FindType(KnownTypeCode.Object); }
static IEnumerable<IType> GetAllValidTypesFromObjectCreation(CSharpAstResolver resolver, ObjectCreateExpression invoke, AstNode parameter) { int index = GetArgumentIndex(invoke.Arguments, parameter); if (index < 0) yield break; var targetResult = resolver.Resolve(invoke.Type); if (targetResult is TypeResolveResult) { var type = ((TypeResolveResult)targetResult).Type; if (type.Kind == TypeKind.Delegate && index == 0) { yield return type; yield break; } foreach (var constructor in type.GetConstructors ()) { if (index < constructor.Parameters.Count) yield return constructor.Parameters [index].Type; } } }
static IEnumerable<IType> GetAllValidTypesFromInvokation(CSharpAstResolver resolver, InvocationExpression invoke, AstNode parameter) { int index = GetArgumentIndex(invoke.Arguments, parameter); if (index < 0) yield break; var targetResult = resolver.Resolve(invoke.Target) as MethodGroupResolveResult; if (targetResult != null) { foreach (var method in targetResult.Methods) { if (index < method.Parameters.Count) { yield return method.Parameters [index].Type; } } foreach (var extMethods in targetResult.GetExtensionMethods ()) { foreach (var extMethod in extMethods) { if (index + 1 < extMethod.Parameters.Count) { yield return extMethod.Parameters [index + 1].Type; } } } } }
public static ResolveResult Resolve(Lazy <ICompilation> compilation, CSharpUnresolvedFile unresolvedFile, SyntaxTree syntaxTree, TextLocation location, out AstNode node, CancellationToken cancellationToken = default(CancellationToken)) { node = syntaxTree.GetNodeAt(location); if (node == null || node is ArrayInitializerExpression) { return(null); } if (node.Parent is UsingAliasDeclaration && node.Role == UsingAliasDeclaration.AliasRole) { var r = new CSharpAstResolver(compilation.Value, syntaxTree, unresolvedFile); return(r.Resolve(((UsingAliasDeclaration)node.Parent).Import, cancellationToken)); } if (CSharpAstResolver.IsUnresolvableNode(node)) { if (node is Identifier) { node = node.Parent; } else if (node.NodeType == NodeType.Token) { if (node.Parent is IndexerExpression || node.Parent is ConstructorInitializer) { // There's no other place where one could hover to see the indexer's tooltip, // so we need to resolve it when hovering over the '[' or ']'. // For constructor initializer, the same applies to the 'base'/'this' token. node = node.Parent; } else { return(null); } } else { // don't resolve arbitrary nodes - we don't want to show tooltips for everything return(null); } } else { // It's a resolvable node. // However, we usually don't want to show the tooltip everywhere // For example, hovering with the mouse over an empty line between two methods causes // node==TypeDeclaration, but we don't want to show any tooltip. if (!node.GetChildByRole(Roles.Identifier).IsNull) { // We'll suppress the tooltip for resolvable nodes if there is an identifier that // could be hovered over instead: return(null); } } if (node == null) { return(null); } if (node.Parent is ObjectCreateExpression && node.Role == Roles.Type) { node = node.Parent; } InvocationExpression parentInvocation = null; if ((node is IdentifierExpression || node is MemberReferenceExpression || node is PointerReferenceExpression) && node.Role != Roles.Argument) { // we also need to resolve the invocation parentInvocation = node.Parent as InvocationExpression; } // TODO: I think we should provide an overload so that an existing CSharpAstResolver can be reused CSharpAstResolver resolver = new CSharpAstResolver(compilation.Value, syntaxTree, unresolvedFile); ResolveResult rr = resolver.Resolve(node, cancellationToken); MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult; if (mgrr != null) { // For method groups, resolve the parent invocation instead. if (parentInvocation != null) { return(resolver.Resolve(parentInvocation)); } if (node is Expression) { // If it's not an invocation, try if it's a conversion to a delegate type: Conversion c = resolver.GetConversion((Expression)node, cancellationToken); if (c.IsMethodGroupConversion) { return(new MemberResolveResult(mgrr.TargetResult, c.Method)); } } } return(rr); }
public BaseRefactoringContext(ICSharpCode.NRefactory.PlayScript.Resolver.CSharpAstResolver resolver, System.Threading.CancellationToken cancellationToken) { this.resolver = resolver; this.cancellationToken = cancellationToken; this.referenceFinder = new LocalReferenceFinder(resolver); }
public ResolveResult GetLanguageItem (MonoDevelop.Ide.Gui.Document doc, int offset, string expression) { if (offset < 0) { return null; } var parsedDocument = doc.ParsedDocument; if (parsedDocument == null) return null; var data = doc.Editor; var loc = data.OffsetToLocation (offset); var unit = parsedDocument.GetAst<SyntaxTree> (); var parsedFile = parsedDocument.ParsedFile as CSharpUnresolvedFile; if (unit == null || parsedFile == null) { return null; } var node = unit.GetNodeAt (loc); if (node == null) { return null; } var resolver = new CSharpAstResolver (doc.Compilation, unit, parsedFile); resolver.ApplyNavigator (new NodeListResolveVisitorNavigator (node), CancellationToken.None); var state = resolver.GetResolverStateBefore (node, CancellationToken.None); return state.LookupSimpleNameOrTypeName (expression, new List<IType> (), NameLookupMode.Expression); }
internal virtual void NavigatorDone(CSharpAstResolver resolver, CancellationToken cancellationToken) { }
public BaseRefactoringContext (ICSharpCode.NRefactory.PlayScript.Resolver.CSharpAstResolver resolver, System.Threading.CancellationToken cancellationToken) { this.resolver = resolver; this.cancellationToken = cancellationToken; this.referenceFinder = new LocalReferenceFinder(resolver); }
public static ReachabilityAnalysis Create(Statement statement, CSharpAstResolver resolver = null, CancellationToken cancellationToken = default(CancellationToken)) { var cfgBuilder = new ControlFlowGraphBuilder(); var cfg = cfgBuilder.BuildControlFlowGraph(statement, resolver, cancellationToken); return Create(cfg, cancellationToken); }