/// <summary> /// Creates a new TypeSystemAstBuilder. /// </summary> /// <param name="resolver"> /// A resolver initialized for the position where the type will be inserted. /// </param> public TypeSystemAstBuilder(CppResolver resolver) { if (resolver == null) throw new ArgumentNullException("resolver"); this.resolver = resolver; InitProperties(); }
/// <summary> /// Creates a new C# AST resolver. /// Use this overload if you are resolving code snippets (not necessarily complete files). /// </summary> /// <param name="resolver">The resolver state at the root node (to be more precise: outside the root node).</param> /// <param name="rootNode">The root node of the resolved tree.</param> /// <param name="parsedFile">The parsed file for the nodes being resolved. This parameter is used only /// when the root node is on the type level; it is not necessary when an expression is passed. /// This parameter may be null.</param> public CppAstResolver(CppResolver resolver, AstNode rootNode, CppParsedFile parsedFile = null) { if (resolver == null) throw new ArgumentNullException("resolver"); if (rootNode == null) throw new ArgumentNullException("rootNode"); this.initialResolverState = resolver; this.rootNode = rootNode; this.parsedFile = parsedFile; this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); }
/// <summary> /// Creates a new C# AST resolver. /// Use this overload if you are resolving within a complete C# file. /// </summary> /// <param name="compilation">The current compilation.</param> /// <param name="parsedFile"> /// Result of the <see cref="TypeSystemConvertVisitor"/> for the file being passed. This is used for setting up the context on the resolver. The parsed file must be registered in the compilation. /// </param> /// <param name="compilationUnit">The compilation unit corresponding to the specified parsed file.</param> public CppAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CppParsedFile parsedFile) { if (compilation == null) throw new ArgumentNullException("compilation"); if (parsedFile == null) throw new ArgumentNullException("parsedFile"); if (compilationUnit == null) throw new ArgumentNullException("compilationUnit"); this.initialResolverState = new CppResolver(compilation); this.rootNode = compilationUnit; this.parsedFile = parsedFile; this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile); }
public override ResolveResult Resolve(CppResolver resolver) { ResolveResult targetRR = target.Resolve(resolver); if (targetRR.IsError) return targetRR; IList<IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext); using (var busyLock = BusyManager.Enter(this)) { if (busyLock.Success) { return resolver.ResolveMemberType(targetRR, identifier, typeArgs); } else { // This can happen for "class Test : $Test.Base$ { public class Base {} }": return ErrorResolveResult.UnknownError; // don't cache this error } } }
void AddContextCompletion (CompletionDataWrapper wrapper, CppResolver state, AstNode node) { if (state != null && !(node is AstType)) { foreach (var variable in state.LocalVariables) { if (variable.Region.IsInside (location.Line, location.Column - 1)) continue; wrapper.AddVariable (variable); } } if (currentMember is IUnresolvedParameterizedMember && !(node is AstType)) { var param = (IParameterizedMember)currentMember.CreateResolved (ctx); foreach (var p in param.Parameters) { wrapper.AddVariable (p); } } if (currentMember is IUnresolvedMethod) { var method = (IUnresolvedMethod)currentMember; foreach (var p in method.TypeParameters) { wrapper.AddTypeParameter (p); } } Predicate<IType> typePred = null; if (node is Attribute) { var attribute = Compilation.FindType (KnownTypeCode.Attribute); typePred = t => { return t.GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (attribute)); }; } AddTypesAndNamespaces (wrapper, state, node, typePred); wrapper.Result.Add (factory.CreateLiteralCompletionData ("global")); if (!(node is AstType)) { if (currentMember != null) { AddKeywords (wrapper, statementStartKeywords); AddKeywords (wrapper, expressionLevelKeywords); } else if (currentType != null) { AddKeywords (wrapper, typeLevelKeywords); } else { AddKeywords (wrapper, globalLevelKeywords); } var prop = currentMember as IUnresolvedProperty; if (prop != null && prop.Setter != null && prop.Setter.Region.IsInside (location)) wrapper.AddCustom ("value"); if (currentMember is IUnresolvedEvent) wrapper.AddCustom ("value"); if (IsInSwitchContext (node)) { wrapper.AddCustom ("case"); } } AddKeywords (wrapper, primitiveTypesKeywords); if (currentMember != null) wrapper.AddCustom ("var"); wrapper.Result.AddRange (factory.CreateCodeTemplateCompletionData ()); if (node != null && node.Role == AstNode.Roles.Argument) { var resolved = ResolveExpression (CSharpParsedFile, node.Parent, Unit); var invokeResult = resolved != null ? resolved.Item1 as CppInvocationResolveResult : null; if (invokeResult != null) { int argNum = 0; foreach (var arg in node.Parent.Children.Where (c => c.Role == AstNode.Roles.Argument)) { if (arg == node) break; argNum++; } var param = argNum < invokeResult.Member.Parameters.Count ? invokeResult.Member.Parameters [argNum] : null; if (param != null && param.Type.Kind == TypeKind.Enum) { AddEnumMembers (wrapper, param.Type, state); } } } }
void AddEnumMembers (CompletionDataWrapper completionList, IType resolvedType, CppResolver state) { if (resolvedType.Kind != TypeKind.Enum) return; string typeString = GetShortType (resolvedType, state); if (typeString.Contains (".")) completionList.AddType (resolvedType, typeString); foreach (var field in resolvedType.GetFields ()) { if (field.IsConst || field.IsStatic) completionList.Result.Add (factory.CreateEntityCompletionData (field, typeString + "." + field.Name)); } DefaultCompletionString = typeString; }
IEnumerable<ICompletionData> CreateCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CppResolver state) { if (resolveResult == null /*|| resolveResult.IsError*/) return null; if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; var namespaceContents = new CompletionDataWrapper (this); foreach (var cl in nr.Namespace.Types) { namespaceContents.AddType (cl, cl.Name); } foreach (var ns in nr.Namespace.ChildNamespaces) { namespaceContents.AddNamespace (ns.Name); } return namespaceContents.Result; } IType type = resolveResult.Type; var typeDef = resolveResult.Type.GetDefinition (); var result = new CompletionDataWrapper (this); bool includeStaticMembers = false; if (resolveResult is LocalResolveResult) { if (resolvedNode is IdentifierExpression) { var mrr = (LocalResolveResult)resolveResult; includeStaticMembers = mrr.Variable.Name == mrr.Type.Name; } } if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) { foreach (var field in type.GetFields ()) { result.AddMember (field); } foreach (var m in type.GetMethods ()) { if (m.Name == "TryParse") result.AddMember (m); } return result.Result; } if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) { var mrr = (MemberResolveResult)resolveResult; includeStaticMembers = mrr.Member.Name == mrr.Type.Name; // ADD Aliases var scope = CSharpParsedFile.GetUsingScope (location).Resolve (Compilation); for (var n = scope; n != null; n = n.Parent) { foreach (var pair in n.UsingAliases) { if (pair.Key == mrr.Member.Name) { foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) { if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) { result.AddMember ((IMember)((IEntityCompletionData)r).Entity); } else { result.Add (r); } } } } } } if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) { includeStaticMembers = true; } // Console.WriteLine ("type:" + type +"/"+type.GetType ()); // Console.WriteLine ("current:" + ctx.CurrentTypeDefinition); // Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers); // Console.WriteLine (resolveResult); // Console.WriteLine ("node:" + resolvedNode); // Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null"); if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression. var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly); bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed (type); var filteredList = new List<IMember> (); foreach (var member in type.GetMembers ()) { // Console.WriteLine ("member:" + member + member.IsShadowing); if (!lookup.IsAccessible (member, isProtectedAllowed)) { // Console.WriteLine ("skip access: " + member.FullName); continue; } if (resolvedNode is BaseReferenceExpression && member.IsAbstract) continue; bool memberIsStatic = member.IsStatic; if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) { // Console.WriteLine ("skip static member: " + member.FullName); continue; } var field = member as IField; if (field != null) memberIsStatic |= field.IsConst; if (!memberIsStatic && (resolveResult is TypeResolveResult)) { continue; } if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") continue; if (member.EntityType == EntityType.Operator) continue; if (member.IsShadowing) filteredList.RemoveAll (m => m.Name == member.Name); filteredList.Add (member); } foreach (var member in filteredList) { // Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic); result.AddMember (member); } } if (resolveResult is TypeResolveResult || includeStaticMembers) { foreach (var nested in type.GetNestedTypes ()) { result.AddType (nested, nested.Name); } } else { foreach (var meths in state.GetExtensionMethods (type)) { foreach (var m in meths) { result.AddMember (m); } } } // IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null); // CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location); // col.HideExtensionParameter = !resolveResult.StaticResolve; // col.NamePrefix = expressionResult.Expression; // bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints); // if (objects != null) { // foreach (object obj in objects) { // if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj)) // continue; // if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace)) // continue; // if (showOnlyTypes && !(obj is IType)) // continue; // CompletionData data = col.Add (obj); // if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) { // string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length); // data.SetText (newText); // } // } // } return result.Result; }
public IList<ResolveResult> GetArgumentsWithConversions() { if (bestCandidate == null) return arguments; var conversions = this.ArgumentConversions; ResolveResult[] args = new ResolveResult[arguments.Length]; for (int i = 0; i < args.Length; i++) { if (conversions[i] == Conversion.IdentityConversion) { args[i] = arguments[i]; } else { int parameterIndex = bestCandidate.ArgumentToParameterMap[i]; IType parameterType; if (parameterIndex >= 0) { parameterType = bestCandidate.ParameterTypes[parameterIndex]; } else { parameterType = SpecialType.UnknownType; } if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) { args[i] = new CppResolver(compilation).ResolveCast(parameterType, arguments[i]); } else { args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]); } } } return args; }
string GetShortType (IType type, CppResolver state) { var builder = new TypeSystemAstBuilder (state); var dt = state.CurrentTypeDefinition; var declaring = type.DeclaringType != null ? type.DeclaringType.GetDefinition () : null; if (declaring != null) { while (dt != null) { if (dt.Equals (declaring)) { builder.AlwaysUseShortTypeNames = true; break; } dt = dt.DeclaringTypeDefinition; } } var shortType = builder.ConvertType (type); using (var w = new System.IO.StringWriter ()) { var visitor = new CppOutputVisitor (w, FormattingPolicy); shortType.AcceptVisitor (visitor, null); return w.ToString (); } }
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveSimpleName(identifier, typeArguments.Resolve(resolver.CurrentTypeResolveContext)); }
/// <summary> /// Returns the type that is referenced; or <see cref="SpecialType.UnknownType"/> if the type isn't found. /// </summary> public IType ResolveType(CppResolver resolver) { TypeResolveResult trr = Resolve(resolver) as TypeResolveResult; return trr != null ? trr.Type : SpecialType.UnknownType; }
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveTypeOf(type.Resolve(resolver.CurrentTypeResolveContext)); }
public override ResolveResult Resolve(CppResolver resolver) { return new ConstantResolveResult(type.Resolve(resolver.CurrentTypeResolveContext), value); }
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveUnaryOperator(operatorType, expression.Resolve(resolver)); }
public override ResolveResult Resolve(CppResolver resolver) { ResolveResult lhs = left.Resolve(resolver); ResolveResult rhs = right.Resolve(resolver); return resolver.ResolveBinaryOperator(operatorType, lhs, rhs); }
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveDefaultValue(type.Resolve(resolver.CurrentTypeResolveContext)); }
public override ResolveResult Resolve(CppResolver resolver) { return expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow)); }
public override ResolveResult Resolve(CppResolver resolver) { ResolveResult rr; if (targetType != null) rr = new TypeResolveResult(targetType.Resolve(resolver.CurrentTypeResolveContext)); else rr = targetExpression.Resolve(resolver); return resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext)); }
void AddTypesAndNamespaces (CompletionDataWrapper wrapper, CppResolver state, AstNode node, Predicate<IType> typePred = null, Predicate<IMember> memberPred = null) { if (currentType != null) { for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) { foreach (var nestedType in ct.NestedTypes) { if (typePred == null || typePred (nestedType.Resolve (ctx))) { string name = nestedType.Name; if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length) name = name.Substring (0, name.Length - "Attribute".Length); wrapper.AddType (nestedType, name); } } } if (this.currentMember != null && !(node is AstType)) { var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition (currentType); if (def != null) { foreach (var member in def.GetMembers ()) { if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") continue; if (member.EntityType == EntityType.Operator) continue; if (memberPred == null || memberPred (member)) wrapper.AddMember (member); } var declaring = def.DeclaringTypeDefinition; while (declaring != null) { foreach (var member in declaring.GetMembers (m => m.IsStatic)) { if (memberPred == null || memberPred (member)) wrapper.AddMember (member); } declaring = declaring.DeclaringTypeDefinition; } } } foreach (var p in currentType.TypeParameters) { wrapper.AddTypeParameter (p); } } var scope = CSharpParsedFile.GetUsingScope (location).Resolve (Compilation); for (var n = scope; n != null; n = n.Parent) { foreach (var pair in n.UsingAliases) { wrapper.AddNamespace (pair.Key); } foreach (var u in n.Usings) { foreach (var type in u.Types) { if (typePred == null || typePred (type)) { string name = type.Name; if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length) name = name.Substring (0, name.Length - "Attribute".Length); wrapper.AddType (type, name); } } } foreach (var type in n.Namespace.Types) { if (typePred == null || typePred (type)) wrapper.AddType (type, type.Name); } foreach (var curNs in n.Namespace.ChildNamespaces) { wrapper.AddNamespace (curNs.Name); } } }
/// <summary> /// Resolves the reference and returns the ResolveResult. /// </summary> public abstract ResolveResult Resolve(CppResolver resolver);
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveConditional( condition.Resolve(resolver), trueExpr.Resolve(resolver), falseExpr.Resolve(resolver) ); }
public override ResolveResult Resolve(CppResolver resolver) { return resolver.ResolveCast(targetType.Resolve(resolver.CurrentTypeResolveContext), expression.Resolve(resolver)); }
List<string> GetUsedNamespaces () { var scope = CSharpParsedFile.GetUsingScope (location); var result = new List<string> (); var resolver = new CppResolver (ctx); while (scope != null) { result.Add (scope.NamespaceName); foreach (var u in scope.Usings) { var ns = u.ResolveNamespace (resolver); if (ns == null) continue; result.Add (ns.FullName); } scope = scope.Parent; } return result; }
public override ResolveResult Resolve(CppResolver resolver) { ResolveResult[] elements = new ResolveResult[arrayElements.Count]; for (int i = 0; i < elements.Length; i++) { elements[i] = arrayElements[i].Resolve(resolver); } if (elementType != null) { return resolver.ResolveArrayCreation(elementType.Resolve(resolver.CurrentTypeResolveContext), 1, null, elements); } else { return resolver.ResolveArrayCreation(null, 1, null, elements); } }
IEnumerable<ICompletionData> MagicKeyCompletion (char completionChar, bool controlSpace) { switch (completionChar) { // Magic key completion case ':': case '.': if (IsInsideCommentOrString ()) return Enumerable.Empty<ICompletionData> (); var expr = GetExpressionBeforeCursor (); if (expr == null) return null; // do not complete <number>. (but <number>.<number>.) if (expr.Item2 is PrimitiveExpression) { var pexpr = (PrimitiveExpression)expr.Item2; if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.')) return null; } var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3); if (resolveResult == null) return null; if (expr.Item2 is AstType) return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2); return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2); case '#': if (IsInsideCommentOrString ()) return null; return GetDirectiveCompletionData (); // XML doc completion case '<': if (IsInsideDocComment ()) return GetXmlDocumentationCompletionData (); if (controlSpace) return DefaultControlSpaceItems (); return null; case '>': if (!IsInsideDocComment ()) return null; string lineText = document.GetText (document.GetLineByNumber (location.Line)); int startIndex = Math.Min (location.Column - 1, lineText.Length - 1); while (startIndex >= 0 && lineText [startIndex] != '<') { --startIndex; if (lineText [startIndex] == '/') { // already closed. startIndex = -1; break; } } if (startIndex >= 0) { int endIndex = startIndex; while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) { endIndex++; } string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null; if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0) document.Insert (offset, "</" + tag + ">"); } return null; // Parameter completion case '(': if (IsInsideCommentOrString ()) return null; var invoke = GetInvocationBeforeCursor (true); if (invoke == null) return null; if (invoke.Item2 is TypeOfExpression) return CreateTypeList (); var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); if (invocationResult == null) return null; var methodGroup = invocationResult.Item1 as MethodGroupResolveResult; if (methodGroup != null) return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace); if (controlSpace) return DefaultControlSpaceItems (invoke); return null; case '=': return controlSpace ? DefaultControlSpaceItems () : null; case ',': int cpos2; if (!GetParameterCompletionCommandOffset (out cpos2)) return null; // completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2); // int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1; // return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter); break; // Completion on space: case ' ': if (IsInsideCommentOrString ()) return null; int tokenIndex = offset; string token = GetPreviousToken (ref tokenIndex, false); // check propose name, for context <variable name> <ctrl+space> (but only in control space context) //IType isAsType = null; var isAsExpression = GetExpressionAt (offset); if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") { var parent = isAsExpression.Item2 as VariableDeclarationStatement; var proposeNameList = new CompletionDataWrapper (this); foreach (var possibleName in GenerateNameProposals (parent.Type)) { if (possibleName.Length > 0) proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ())); } AutoSelect = false; AutoCompleteEmptyMatch = false; return proposeNameList.Result; } // int tokenIndex = offset; // string token = GetPreviousToken (ref tokenIndex, false); // if (result.ExpressionContext == ExpressionContext.ObjectInitializer) { // resolver = CreateResolver (); // ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType); // IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType; // if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ",")) // return CreateCtrlSpaceCompletionData (completionContext, result); // } if (token == "=") { int j = tokenIndex; string prevToken = GetPreviousToken (ref j, false); if (prevToken == "=" || prevToken == "+" || prevToken == "-") { token = prevToken + token; tokenIndex = j; } } switch (token) { case "(": case ",": int cpos; if (!GetParameterCompletionCommandOffset (out cpos)) break; int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1; if (currentParameter < 0) return null; invoke = GetInvocationBeforeCursor (token == "("); if (invoke == null) return null; invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3); if (invocationResult == null) return null; methodGroup = invocationResult.Item1 as MethodGroupResolveResult; if (methodGroup != null) return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace); return null; case "=": case "==": GetPreviousToken (ref tokenIndex, false); var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex); if (expressionOrVariableDeclaration == null) return null; resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3); if (resolveResult == null) return null; if (resolveResult.Item1.Type.Kind == TypeKind.Enum) { var wrapper = new CompletionDataWrapper (this); AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2); AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2); AutoCompleteEmptyMatch = false; return wrapper.Result; } // // if (resolvedType.FullName == DomReturnType.Bool.FullName) { // CompletionDataList completionList = new ProjectDomCompletionDataList (); // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); // completionList.AutoCompleteEmptyMatch = false; // cdc.Add ("true", "md-keyword"); // cdc.Add ("false", "md-keyword"); // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); // return completionList; // } // if (resolvedType.ClassType == ClassType.Delegate && token == "=") { // CompletionDataList completionList = new ProjectDomCompletionDataList (); // string parameterDefinition = AddDelegateHandlers (completionList, resolvedType); // string varName = GetPreviousMemberReferenceExpression (tokenIndex); // completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType)); // // CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location); // resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc); // foreach (var data in completionList) { // if (data is MemberCompletionData) // ((MemberCompletionData)data).IsDelegateExpected = true; // } // return completionList; // } return null; case "+=": case "-=": GetPreviousToken (ref tokenIndex, false); expressionOrVariableDeclaration = GetExpressionAt (tokenIndex); if (expressionOrVariableDeclaration == null) return null; resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3); if (resolveResult == null) return null; var mrr = resolveResult.Item1 as MemberResolveResult; if (mrr != null) { var evt = mrr.Member as IEvent; if (evt == null) return null; var delegateType = evt.ReturnType; if (delegateType.Kind != TypeKind.Delegate) return null; var wrapper = new CompletionDataWrapper (this); if (currentType != null) { // bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType); foreach (var method in currentType.Methods) { if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) { wrapper.AddMember (method); // data.SetText (data.CompletionText + ";"); } } } if (token == "+=") { string parameterDefinition = AddDelegateHandlers (wrapper, delegateType); string varName = GetPreviousMemberReferenceExpression (tokenIndex); wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType)); } return wrapper.Result; } return null; case ":": /* Breaks constructor initializer case: * if (currentMember == null) { var wrapper = new CompletionDataWrapper (this); AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true); return wrapper.Result; }*/ return null; } var keywordCompletion = HandleKeywordCompletion (tokenIndex, token); if (keywordCompletion == null && controlSpace) goto default; return keywordCompletion; // Automatic completion default: if (IsInsideCommentOrString ()) return null; if (IsInLinqContext (offset)) { if (!controlSpace && !(char.IsLetter (completionChar) || completionChar == '_')) return null; tokenIndex = offset; token = GetPreviousToken (ref tokenIndex, false); // token last typed if (!char.IsWhiteSpace (completionChar) && !linqKeywords.Contains (token)) token = GetPreviousToken (ref tokenIndex, false); // token last typed if (linqKeywords.Contains (token)) { if (token == "from") // after from no auto code completion. return null; return DefaultControlSpaceItems (); } var dataList = new CompletionDataWrapper (this); AddKeywords (dataList, linqKeywords); return dataList.Result; } if (currentType != null && currentType.Kind == TypeKind.Enum) return HandleEnumContext (); var contextList = new CompletionDataWrapper (this); var identifierStart = GetExpressionAtCursor (); if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration) return null; if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null; } if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) { return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null; } char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';'; char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' '; const string allowedChars = ";,[](){}+-*/%^?:&|~!<>="; if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0) return null; if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0)) return null; // Do not pop up completion on identifier identifier (should be handled by keyword completion). tokenIndex = offset - 1; token = GetPreviousToken (ref tokenIndex, false); if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") // after these always follows a name return null; int prevTokenIndex = tokenIndex; var prevToken2 = GetPreviousToken (ref prevTokenIndex, false); if (prevToken2 == "delegate") // after these always follows a name return null; if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) { char last = token [token.Length - 1]; if (char.IsLetterOrDigit (last) || last == '_' || token == ">") { return HandleKeywordCompletion (tokenIndex, token); } } if (identifierStart == null) { var accCtx = HandleAccessorContext (); if (accCtx != null) return accCtx; return DefaultControlSpaceItems (null, controlSpace); } CppResolver csResolver; AstNode n = identifierStart.Item2; if (n != null && n.Parent is AnonymousTypeCreateExpression) { AutoSelect = false; } // Handle foreach (type name _ if (n is IdentifierExpression) { var prev = n.GetPrevNode () as ForeachStatement; if (prev != null && prev.InExpression.IsNull) { if (controlSpace) { contextList.AddCustom ("in"); return contextList.Result; } return null; } } if (n != null && n.Parent is InvocationExpression) { var invokeParent = (InvocationExpression)n.Parent; var invokeResult = ResolveExpression (identifierStart.Item1, invokeParent.Target, identifierStart.Item3); var mgr = invokeResult != null ? invokeResult.Item1 as MethodGroupResolveResult : null; if (mgr != null) { int idx = 0; foreach (var arg in invokeParent.Arguments) { if (arg == n) break; idx++; } foreach (var method in mgr.Methods) { if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) { AutoSelect = false; AutoCompleteEmptyMatch = false; } foreach (var p in method.Parameters) { contextList.AddVariable (p); } } idx++; foreach (var list in mgr.GetExtensionMethods ()) { foreach (var method in list) { if (idx < method.Parameters.Count && method.Parameters[idx].Type.Kind == TypeKind.Delegate) { AutoSelect = false; AutoCompleteEmptyMatch = false; } } } } } if (n != null && n.Parent is ObjectCreateExpression) { var invokeResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3); var mgr = invokeResult != null ? invokeResult.Item1 as ResolveResult : null; if (mgr != null) { foreach (var constructor in mgr.Type.GetConstructors ()) { foreach (var p in constructor.Parameters) { contextList.AddVariable (p); } } } } if (n is IdentifierExpression) { var bop = n.Parent as BinaryOperatorExpression; Expression evaluationExpr = null; if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) { evaluationExpr = bop.Left; } // check for compare to enum case if (evaluationExpr != null) { resolveResult = ResolveExpression (identifierStart.Item1, evaluationExpr, identifierStart.Item3); if (resolveResult != null && resolveResult.Item1.Type.Kind == TypeKind.Enum) { var wrapper = new CompletionDataWrapper (this); AddContextCompletion (wrapper, resolveResult.Item2, evaluationExpr); AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2); AutoCompleteEmptyMatch = false; return wrapper.Result; } } } if (n is Identifier && n.Parent is ForeachStatement) { if (controlSpace) return DefaultControlSpaceItems (); return null; } if (n is ArrayInitializerExpression) { // check for new [] {...} expression -> no need to resolve the type there var parent = n.Parent as ArrayCreateExpression; if (parent != null && parent.Type.IsNull) return DefaultControlSpaceItems (); var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3); var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location); // check if we're on the right side of an initializer expression if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) { return DefaultControlSpaceItems (); } if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) { foreach (var property in initalizerResult.Item1.Type.GetProperties ()) { if (!property.IsPublic) continue; contextList.AddMember (property); } foreach (var field in initalizerResult.Item1.Type.GetFields ()) { if (!field.IsPublic) continue; contextList.AddMember (field); } return contextList.Result; } return DefaultControlSpaceItems (); } if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) { csResolver = new CppResolver (ctx); var nodes = new List<AstNode> (); nodes.Add (n); if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute) nodes.Add (n.Parent); var astResolver = new CppAstResolver (csResolver, identifierStart.Item3, identifierStart.Item1); astResolver.ApplyNavigator (new NodeListResolveVisitorNavigator (nodes)); try { csResolver = astResolver.GetResolverStateBefore (n); } catch (Exception) { csResolver = GetState (); } // add attribute properties. if (n.Parent is ICSharpCode.NRefactory.Cpp.Attribute) { var resolved = astResolver.Resolve (n.Parent); if (resolved != null && resolved.Type != null) { foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) { contextList.AddMember (property); } foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) { contextList.AddMember (field); } } } } else { csResolver = GetState (); } // identifier has already started with the first letter offset--; AddContextCompletion (contextList, csResolver, identifierStart.Item2); return contextList.Result; // if (stub.Parent is BlockStatement) // result = FindExpression (dom, completionContext, -1); // if (result == null) // return null; // else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) { // triggerWordLength = 1; // bool autoSelect = true; // IType returnType = null; // if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) { // ctx = CompletionWidget.CreateCodeCompletionContext (cpos); // NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider; // if (dataProvider != null) { // int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1; // foreach (var method in dataProvider.Methods) { // if (i < method.Parameters.Count) { // returnType = dom.GetType (method.Parameters [i].ReturnType); // autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate; // break; // } // } // } // } // // Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature // //if (result.ExpressionContext == ExpressionContext.TypeName) // // autoSelect = false; // CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result); // AddEnumMembers (dataList, returnType); // dataList.AutoSelect = autoSelect; // return dataList; // } else { // result = FindExpression (dom, completionContext, 0); // tokenIndex = offset; // // // check foreach case, unfortunately the expression finder is too dumb to handle full type names // // should be overworked if the expression finder is replaced with a mcs ast based analyzer. // var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname // // // read return types to '(' token // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType // if (possibleForeachToken == ">") { // while (possibleForeachToken != null && possibleForeachToken != "(") { // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // } // } else { // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // ( // if (possibleForeachToken == ".") // while (possibleForeachToken != null && possibleForeachToken != "(") // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // } // possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach // // if (possibleForeachToken == "foreach") { // result.ExpressionContext = ExpressionContext.ForeachInToken; // } else { // return null; // // result.ExpressionContext = ExpressionContext.IdentifierExpected; // } // result.Expression = ""; // result.Region = DomRegion.Empty; // // return CreateCtrlSpaceCompletionData (completionContext, result); // } // break; } return null; }
IEnumerable<ICompletionData> CreateTypeAndNamespaceCompletionData (TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CppResolver state) { if (resolveResult == null || resolveResult.IsError) return null; var result = new CompletionDataWrapper (this); if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; foreach (var cl in nr.Namespace.Types) { result.AddType (cl, cl.Name); } foreach (var ns in nr.Namespace.ChildNamespaces) { result.AddNamespace (ns.Name); } } else if (resolveResult is TypeResolveResult) { var type = resolveResult.Type; foreach (var nested in type.GetNestedTypes ()) { result.AddType (nested, nested.Name); } } return result.Result; }
/// <summary> /// Returns the namespace that is referenced; or null if no such namespace is found. /// </summary> public INamespace ResolveNamespace(CppResolver resolver) { NamespaceResolveResult nrr = Resolve(resolver) as NamespaceResolveResult; return nrr != null ? nrr.Namespace : null; }
IEnumerable<ICompletionData> CreateParameterCompletion (MethodGroupResolveResult resolveResult, CppResolver state, AstNode invocation, int parameter, bool controlSpace) { var result = new CompletionDataWrapper (this); var addedEnums = new HashSet<string> (); var addedDelegates = new HashSet<string> (); foreach (var method in resolveResult.Methods) { if (method.Parameters.Count <= parameter) continue; var resolvedType = method.Parameters [parameter].Type; if (resolvedType.Kind == TypeKind.Enum) { if (addedEnums.Contains (resolvedType.ReflectionName)) continue; addedEnums.Add (resolvedType.ReflectionName); AddEnumMembers (result, resolvedType, state); } else if (resolvedType.Kind == TypeKind.Delegate) { // if (addedDelegates.Contains (resolvedType.DecoratedFullName)) // continue; // addedDelegates.Add (resolvedType.DecoratedFullName); // string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1); // string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name; // result.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false }); } } if (!controlSpace) { if (addedEnums.Count + addedDelegates.Count == 0) return Enumerable.Empty<ICompletionData> (); AutoCompleteEmptyMatch = false; AutoSelect = false; } AddContextCompletion (result, state, invocation); // resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc); // if (addedDelegates.Count > 0) { // foreach (var data in result.Result) { // if (data is MemberCompletionData) // ((MemberCompletionData)data).IsDelegateExpected = true; // } // } return result.Result; }
public ObjectInitializerContext(IType type, CppResolver.ObjectInitializerContext prev) { this.type = type; this.prev = prev; }
public override ResolveResult Resolve(CppResolver resolver) { var typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext); return resolver.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode); }