public void Validates_only_expression_that_isnt_member_nor_type()
        {
            MemberResolveResult result = new MemberResolveResult(null){
                ResolvedMember = null,
                ResolvedType = new DomReturnType{Type = null},
                ResolvedExpression = new ExpressionResult("SomeClass")
            };
            ctx.Stub(p=>p.GetResolvedTypeNameResult()).Return(result);

            Assert.IsTrue(generateClassRefactoring.IsValid());
        }
Example #2
0
		ResolveResult CreateResult (ICompilationUnit unit, IReturnType type)
		{
			MemberResolveResult result = new MemberResolveResult (null);
			result.CallingType   = resolver.CallingType;
			result.CallingMember = resolver.CallingMember;
			result.ResolvedType = type;
			result.UnresolvedType = type;
			if (unit != null && resolver.Dom != null && type != null && type.Type == null) {
				IType searchedType = resolver.SearchType (type);
				if (searchedType != null) {
					DomReturnType resType = new DomReturnType (searchedType);
					resType.ArrayDimensions = type.ArrayDimensions;
					for (int i = 0; i < type.ArrayDimensions; i++) {
						resType.SetDimension (i, type.GetDimension (i));
					}
					resType.PointerNestingLevel = type.PointerNestingLevel;
					result.ResolvedType = resType;
				}
			}
			return result;
		}
Example #3
0
		public CombinedMethodResolveResult (MemberResolveResult baseResolveResult, MethodResolveResult methodResolveResult)
		{
			BaseResolveResult = baseResolveResult;
			MethodResolveResult = methodResolveResult;
			CallingType = baseResolveResult.CallingType;
			CallingMember = baseResolveResult.CallingMember;
			StaticResolve = baseResolveResult.StaticResolve;
			ResolvedMember = baseResolveResult.ResolvedMember;
			ResolvedExpression = baseResolveResult.ResolvedExpression;
		}
        public void SetTest()
        {
            AnonymousType anonymousType = new AnonymousType {Namespace = nmspc};
            resolvedResult = new MemberResolveResult(anonymousType);
            resolvedResult.CallingType = anonymousType;
            resolvedResult.ResolvedExpression = new ExpressionResult(clsName);
            ctx.Stub(p=>p.GetResolvedTypeNameResult()).Return(resolvedResult);
            ctx.Stub(p=>p.GetCurrentFilePath()).Return(new FilePath(dir + fileName));

            resolver.Stub(r=>r.GetNewTypeContent(Arg<string>.Is.Anything, Arg<string>.Is.Anything, Arg<string>.Is.Anything)).Return (fileContent);

            changes = generateClassRefactoring.PerformChanges(null, null);
        }
		public MonoDevelop.Projects.Dom.ResolveResult GetLanguageItem (ProjectDom dom, Mono.TextEditor.TextEditorData data, int offset)
		{
			if (offset < 0)
				return null;
			string fileName = data.Document.FileName;
			IParser parser = ProjectDomService.GetParser (fileName, data.Document.MimeType);
			if (parser == null)
				return null;
			
			MonoDevelop.Ide.Gui.Document doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null)
				return null;
			
			IResolver         resolver = parser.CreateResolver (dom, doc, fileName);
			IExpressionFinder expressionFinder = parser.CreateExpressionFinder (dom);
			if (resolver == null || expressionFinder == null) 
				return null;
			
			string txt = data.Document.Text;
			int wordEnd = offset;
			while (wordEnd < txt.Length && (Char.IsLetterOrDigit (txt[wordEnd]) || txt[wordEnd] == '_'))
				wordEnd++;
			
			while (wordEnd < txt.Length - 1 && Char.IsWhiteSpace (txt[wordEnd]))
				wordEnd++;
			
			if (wordEnd < txt.Length && txt[wordEnd] == '<') {
				bool wasMethodCall = false;
				int saveEnd = wordEnd;
				int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd);
				if (matchingBracket > 0)
					wordEnd = matchingBracket;
				while (wordEnd < txt.Length - 1 && Char.IsWhiteSpace (txt[wordEnd]))
					wordEnd++;
				if (txt[wordEnd] == '(') {
					matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd);
					if (matchingBracket > 0) {
						wordEnd = matchingBracket;
						wasMethodCall = true;
					}
				}
				if (!wasMethodCall)
					wordEnd = saveEnd;
			}

			ExpressionResult expressionResult = expressionFinder.FindExpression (txt, wordEnd);
			if (expressionResult == null)
				return null;
			ResolveResult resolveResult;
			DocumentLocation loc = data.Document.OffsetToLocation (offset);
			string savedExpression = null;
			
			// special handling for 'var' "keyword"
			if (expressionResult.ExpressionContext == ExpressionContext.IdentifierExpected && expressionResult.Expression != null && expressionResult.Expression.Trim () == "var") {
				int endOffset = data.Document.LocationToOffset (expressionResult.Region.End.Line - 1, expressionResult.Region.End.Column - 1);
				StringBuilder identifer = new StringBuilder ();
				for (int i = endOffset; i >= 0 && i < data.Document.Length; i++) {
					char ch = data.Document.GetCharAt (i);
					if (Char.IsWhiteSpace (ch))
						continue;
					if (ch == '=')
						break;
					if (Char.IsLetterOrDigit (ch) || ch =='_') {
						identifer.Append (ch);
						continue;
					}
					identifer.Length = 0;
					break;
				}
				if (identifer.Length > 0) {
					expressionResult.Expression = identifer.ToString ();
					resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line + 1, loc.Column + 1));
					if (resolveResult != null) {
						resolveResult = new MemberResolveResult (dom.GetType (resolveResult.ResolvedType));
						return resolveResult;
					}
				}
			}
			
			if (expressionResult.ExpressionContext == ExpressionContext.Attribute) {
				savedExpression = expressionResult.Expression;
				expressionResult.Expression += "Attribute";
				expressionResult.ExpressionContext = ExpressionContext.ObjectCreation;
			} 
			resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line + 1, loc.Column + 1));
			
			if (savedExpression != null && resolveResult == null) {
				expressionResult.Expression = savedExpression;
				resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line + 1, loc.Column + 1));
			}
			// Search for possible generic parameters.
//			if (this.resolveResult == null || this.resolveResult.ResolvedType == null || String.IsNullOrEmpty (this.resolveResult.ResolvedType.Name)) {
			if (!expressionResult.Region.IsEmpty) {
				int j = data.Document.LocationToOffset (expressionResult.Region.End.Line - 1, expressionResult.Region.End.Column - 1);
				int bracket = 0;
				for (int i = j; i >= 0 && i < data.Document.Length; i++) {
					char ch = data.Document.GetCharAt (i);
					if (Char.IsWhiteSpace (ch))
						continue;
					if (ch == '<') {
						bracket++;
					} else if (ch == '>') {
						bracket--;
						if (bracket == 0) {
							expressionResult.Expression += data.Document.GetTextBetween (j, i + 1);
							expressionResult.ExpressionContext = ExpressionContext.ObjectCreation;
							resolveResult = resolver.Resolve (expressionResult, new DomLocation (loc.Line + 1, loc.Column + 1));
							break;
						}
					} else {
						if (bracket == 0)
							break;
					}
				}
			}
			
			// To resolve method overloads the full expression must be parsed.
			// ex.: Overload (1)/ Overload("one") - parsing "Overload" gives just a MethodResolveResult
			// and for constructor initializers it's tried too to to resolve constructor overloads.
			if (resolveResult is ThisResolveResult || 
			    resolveResult is BaseResolveResult || 
			    resolveResult is MethodResolveResult && ((MethodResolveResult)resolveResult).Methods.Count > 1) {
				// put the search offset at the end of the invocation to be able to find the full expression
				// the resolver finds it itself if spaces are between the method name and the argument opening parentheses.
				while (wordEnd < txt.Length - 1 && Char.IsWhiteSpace (txt[wordEnd]))
					wordEnd++;
				if (txt[wordEnd] == '(') {
					int matchingBracket = data.Document.GetMatchingBracketOffset (wordEnd);
					if (matchingBracket > 0)
						wordEnd = matchingBracket;
				}
				//Console.WriteLine (expressionFinder.FindFullExpression (txt, wordEnd));
				ResolveResult possibleResult = resolver.Resolve (expressionFinder.FindFullExpression (txt, wordEnd), new DomLocation (loc.Line + 1, loc.Column + 1)) ?? resolveResult;
				//Console.WriteLine ("possi:" + resolver.Resolve (expressionFinder.FindFullExpression (txt, wordEnd), new DomLocation (loc.Line + 1, loc.Column + 1)));
				if (possibleResult is MethodResolveResult)
					resolveResult = possibleResult;
			}
			return resolveResult;
		}
        public ResolveResult ResolveIdentifier(ResolveVisitor visitor, string identifier)
        {
            ResolveResult result = null;
             			if (resultTable.TryGetValue (identifier, out result))
             				return result;
             			resultTable[identifier] = result;

            foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in this.lookupTableVisitor.Variables) {
             				if (identifier == pair.Key) {
             					LocalLookupVariable var = null;
            // 					Console.WriteLine ("--- RP:" + this.resolvePosition + "/" + pair.Value.Count);
                    foreach (LocalLookupVariable v2 in pair.Value) {
                        DomLocation varStartPos = new DomLocation (lookupVariableLine + v2.StartPos.Line, v2.StartPos.Column - 1);
                        DomLocation varEndPos   = new DomLocation (lookupVariableLine + v2.EndPos.Line, v2.EndPos.Column - 1);
            //						Console.WriteLine (v2.Name + ":" + varStartPos + " <> " + varEndPos);
                        if (varStartPos > this.resolvePosition || (!v2.EndPos.IsEmpty && varEndPos < this.resolvePosition))
                            continue;
                        var = v2;
                    }
            //					Console.WriteLine ("var:" + var);
                    if (var == null)
                        continue;
                    IReturnType varType = null;
                    IReturnType varTypeUnresolved = null;
                    if (var.IsQueryContinuation) {
                        QueryExpression query = var.Initializer as QueryExpression;

                        QueryExpressionGroupClause grouBy = query.SelectOrGroupClause as QueryExpressionGroupClause;
                        DomLocation old = resolvePosition;
                        try {
                            resolvePosition = new DomLocation (lookupVariableLine + grouBy.Projection.StartLocation.Line,
                                                               grouBy.Projection.StartLocation.Column);
                            ResolveResult initializerResolve = visitor.Resolve (grouBy.Projection);
                            ResolveResult groupByResolve = visitor.Resolve (grouBy.GroupBy);
                            DomReturnType resolved = new DomReturnType (dom.GetType ("System.Linq.IGrouping", new IReturnType [] {
                                DomType.GetComponentType (dom, initializerResolve.ResolvedType), groupByResolve.ResolvedType}));
                        varTypeUnresolved = varType = resolved;
                        } finally {
                            resolvePosition = old;
                        }

                    } else if ((var.TypeRef == null || var.TypeRef.Type == "var" || var.TypeRef.IsNull)) {
                        if (var.ParentLambdaExpression != null) {
                            ResolveResult lambdaResolve = ResolveLambda (visitor, var.ParentLambdaExpression);
                            if (lambdaResolve != null) {
                                varType           = lambdaResolve.ResolvedType;
                                varTypeUnresolved = lambdaResolve.UnresolvedType;
                            } else {
                                varType = varTypeUnresolved = DomReturnType.Void;
                            }
                        }
                        if (var.Initializer != null) {
                            ResolveResult initializerResolve = visitor.Resolve (var.Initializer);
            //							Console.WriteLine ("initializer : "+ var.Initializer + " result:" + initializerResolve);
                            varType           = var.IsLoopVariable ? DomType.GetComponentType (dom, initializerResolve.ResolvedType) : initializerResolve.ResolvedType;
                            varTypeUnresolved = var.IsLoopVariable ? DomType.GetComponentType (dom, initializerResolve.UnresolvedType) : initializerResolve.UnresolvedType;
            //							Console.WriteLine ("resolved type:" + initializerResolve.ResolvedType + " is loop : " + var.IsLoopVariable);
            //							Console.WriteLine (varType);
            //							Console.WriteLine ("----------");
                        }
                    } else {
                        varTypeUnresolved = varType = ConvertTypeReference (var.TypeRef);
                    }
            //					Console.WriteLine ("-----");
            //					Console.WriteLine (varType);
                    varType = ResolveType (varType);
                    result = new LocalVariableResolveResult (
                        new LocalVariable (CallingMember, identifier, varType,
                            new DomRegion (lookupVariableLine + var.StartPos.Line - 1, var.StartPos.Column - 1,
                                           lookupVariableLine + var.StartPos.Line - 1, var.EndPos.Column - 1)),
                            var.IsLoopVariable);

                    result.ResolvedType = varType;
                    result.UnresolvedType = varTypeUnresolved;
                    goto end;
                }
            }
            if (this.callingMember != null) {
                // special handling of property or field return types, they can have the same name as the return type
                // ex.: MyType MyType { get; set; }  Type1 Type1;
                if ((callingMember is IProperty || callingMember is IField) && identifier == callingMember.Name) {
                    int pos = editor.GetPositionFromLineColumn (resolvePosition.Line, resolvePosition.Column);
                    while (pos < editor.TextLength && !Char.IsWhiteSpace (editor.GetCharAt (pos)))
                        pos++;
                    while (pos < editor.TextLength && Char.IsWhiteSpace (editor.GetCharAt (pos)))
                        pos++;
                    StringBuilder memberName = new StringBuilder ();
                    while (pos < editor.TextLength && (Char.IsLetterOrDigit (editor.GetCharAt (pos)) || editor.GetCharAt (pos) == '_') ) {
                        memberName.Append (editor.GetCharAt (pos));
                        pos++;
                    }
                    //Console.WriteLine ("id: '" + identifier + "' : '" + memberName.ToString () +"'" + (memberName.ToString () == identifier));
                    if (memberName.ToString () == identifier) {
                        result = visitor.CreateResult (callingMember.ReturnType);
                        goto end;
                    }
                }

                if (identifier == "value" && this.callingMember is IProperty) {
                    result = new MemberResolveResult (this.callingMember);
                    result.UnresolvedType = ((IProperty)this.callingMember).ReturnType;
                    result.ResolvedType = ResolveType (((IProperty)this.callingMember).ReturnType);
                    goto end;
                }
                if (this.callingMember is IMethod || this.callingMember is IProperty) {
                    ReadOnlyCollection<IParameter> prms = this.callingMember is IMethod
                        ? ((IMethod)this.callingMember).Parameters
                        : ((IProperty)this.callingMember).Parameters;
                    if (prms != null) {
                        foreach (IParameter para in prms) {
                            if (para.Name == identifier) {
                                result = new ParameterResolveResult (para);
                                result.UnresolvedType = para.ReturnType;
                                result.ResolvedType = ResolveType (para.ReturnType);
                                goto end;
                            }
                        }
                    }
                }
            }
            IType searchedType = dom.SearchType (new SearchTypeRequest (unit, this.CallingType, identifier));
            if (this.callingType != null && dom != null) {
                List<IMember> members = new List <IMember> ();
                foreach (IType type in dom.GetInheritanceTree (callingType)) {
                    members.AddRange (type.SearchMember (identifier, true));
                }
                bool includeProtected = true;
                // filter members
                if (this.CallingMember != null) {
                    for (int i = 0; i < members.Count; i++) {
                        if (this.CallingMember.IsStatic && !members[i].IsStatic
                            || !members[i].IsAccessibleFrom (dom, callingType, this.CallingMember, includeProtected))
                        {
                            members.RemoveAt (i);
                            i--;
                            continue;
                        }
                    }
                }

                if (members.Count > 0) {
                    if (members[0] is IMethod) {
                        result = new MethodResolveResult (members);
                        if (CallingMember != null)
                            result.StaticResolve = CallingMember.IsStatic;
                    } else if (members[0] is IType) {
                        result = new MemberResolveResult (null, true);
                        result.UnresolvedType = result.ResolvedType = new DomReturnType ((IType)members[0]);
                        goto end;
                    } else {
                        result = new MemberResolveResult (members[0]);
                    }
                    result.UnresolvedType = members[0].ReturnType;
                    result.ResolvedType = ResolveType (members[0].ReturnType);
                    if (members[0] is IProperty && searchedType != null && result.ResolvedType.FullName == searchedType.FullName) {
                        result = new AggregatedResolveResult (result, new MemberResolveResult (null, true) {
                            UnresolvedType = new DomReturnType (searchedType),
                            ResolvedType = new DomReturnType (searchedType)
                        });
                    }
                    goto end;
                }
            }

            if (searchedType != null) {
                result = new MemberResolveResult (null, true);
                result.UnresolvedType = result.ResolvedType = new DomReturnType (searchedType);
                goto end;
            }

            if (dom.NamespaceExists (identifier, true)) {
                result = new NamespaceResolveResult (identifier);
                goto end;
            }

            if (unit != null && unit.Usings != null) {
                foreach (IUsing u in unit.Usings) {
                    if (u.IsFromNamespace && u.Region.Contains (resolvePosition)) {
                        foreach (string ns in u.Namespaces) {
                            if (dom.NamespaceExists (ns + "."  + identifier, true)) {
                                result = new NamespaceResolveResult (ns + "."  + identifier);
                                goto end;
                            }
                        }
                    }
                    foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
                        if (alias.Key == identifier || alias.Key + ".?" == identifier) {
                            result = new NamespaceResolveResult (alias.Value.FullName);
                            goto end;
                        }
                    }
                }
            }

            end:
            if (result != null) {
                result.CallingType   = CallingType;
                result.CallingMember = CallingMember;
            }
            resultTable[identifier] = result;
            return result;
        }