static void RenameMember(ClassModel inClass, string name, string newName, bool outputResults) { MemberModel m = inClass.Members.Items.FirstOrDefault(it => it.Name == name); if (m == null) return; ASResult result = new ASResult(); ASComplete.FindMember(name, inClass, result, FlagType.Dynamic | FlagType.Function, 0); if (result.Member == null) return; queue.Add(new Rename(result, outputResults, newName)); }
internal static ASResult FindGetterSetter(ASResult target, string name) { var inClass = target.InClass; var members = inClass.Members.Items; for (int i = 0, length = members.Count; i < length; i++) { var member = members[i]; if (member.Name == name) { var result = new ASResult(); ASComplete.FindMember(name, inClass, result, FlagType.Dynamic | FlagType.Function, 0); if (result.Member != null) { return result; } } } return null; }
public static void AddToQueue(ASResult target, bool outputResults) { string originalName = RefactoringHelper.GetRefactorTargetName(target); string label = TextHelper.GetString("Label.NewName"); string title = string.Format(TextHelper.GetString("Title.RenameDialog"), originalName); LineEntryDialog askName = new LineEntryDialog(title, label, originalName); if (askName.ShowDialog() == DialogResult.OK) { string newName = askName.Line.Trim(); if (newName.Length == 0 || newName == originalName) return; queue.Add(new Rename(target, outputResults, newName)); if (ASContext.Context.CurrentModel.haXe && target.Member != null && (target.Member.Flags & (FlagType.Getter | FlagType.Setter)) > 0) { List<MemberModel> list = target.Member.Parameters; if (list[0].Name == "get") RenameMember(target.InClass, "get_" + originalName, "get_" + newName, outputResults); if (list[1].Name == "set") RenameMember(target.InClass, "set_" + originalName, "set_" + newName, outputResults); } if (currentCommand == null) ExecuteFirst(); } }
private static StatementReturnType GetStatementReturnType(ScintillaNet.ScintillaControl Sci, ClassModel inClass, string line, int startPos) { Regex target = new Regex(@"[;\s\n\r]*", RegexOptions.RightToLeft); Match m = target.Match(line); if (!m.Success) { return null; } line = line.Substring(0, m.Index); if (line.Length == 0) { return null; } line = ReplaceAllStringContents(line); ASResult resolve = null; int pos = -1; string word = null; int stylemask = (1 << Sci.StyleBits) - 1; ClassModel type = null; if (line[line.Length - 1] == ')') { pos = -1; int lastIndex = 0; int bracesBalance = 0; while (true) { int pos1 = line.IndexOf("(", lastIndex); int pos2 = line.IndexOf(")", lastIndex); if (pos1 != -1 && pos2 != -1) { lastIndex = Math.Min(pos1, pos2); } else if (pos1 != -1 || pos2 != -1) { lastIndex = Math.Max(pos1, pos2); } else { break; } if (lastIndex == pos1) { bracesBalance++; if (bracesBalance == 1) { pos = lastIndex; } } else if (lastIndex == pos2) { bracesBalance--; } lastIndex++; } } else { pos = line.Length; } if (pos != -1) { line = line.Substring(0, pos); pos += startPos; pos -= line.Length - line.TrimEnd().Length + 1; pos = Sci.WordEndPosition(pos, true); resolve = ASComplete.GetExpressionType(Sci, pos); word = Sci.GetWordFromPosition(pos); } char c = (char)Sci.CharAt(pos); if (word != null && Char.IsDigit(word[0])) { type = inClass.InFile.Context.ResolveType("Number", inClass.InFile); } else if (word != null && (word == "true" || word == "false")) { type = inClass.InFile.Context.ResolveType("Boolean", inClass.InFile); } else if (!(ASComplete.IsTextStyle(Sci.StyleAt(pos - 1) & stylemask))) { type = inClass.InFile.Context.ResolveType("String", inClass.InFile); } else if (c == '}') { type = inClass.InFile.Context.ResolveType("Object", inClass.InFile); } else if (c == '>') { type = inClass.InFile.Context.ResolveType("XML", inClass.InFile); } else if (c == ']') { type = inClass.InFile.Context.ResolveType("Array", inClass.InFile); } if (resolve == null) { resolve = new ASResult(); } if (resolve.Type == null) { resolve.Type = type; } return new StatementReturnType(resolve, pos, word); }
public static MemberModel GetRefactoringTarget(ASResult target) { var type = target.Type; var member = target.Member; if (type.IsEnum() || !type.IsVoid() && target.IsStatic && (member == null || (member.Flags & FlagType.Constructor) > 0)) return type; return member; }
public virtual Command CreateRenameCommandAndExecute(ASResult target, bool outputResults, string newName, bool ignoreDeclarationSource, bool inline = false) { return(new Rename(target, outputResults, newName, ignoreDeclarationSource, inline)); }
/// <summary> /// Finds the given target in all project files. /// If the target is a local variable or function parameter, it will only search the associated file. /// Note: if running asynchronously, you must supply a listener to "findFinishedHandler" to retrieve the results. /// If running synchronously, do not set listeners and instead use the return value. /// </summary> /// <param name="target">the source member to find references to</param> /// <param name="progressReportHandler">event to fire as search results are compiled</param> /// <param name="findFinishedHandler">event to fire once searching is finished</param> /// <param name="asynchronous">executes in asynchronous mode</param> /// <returns>If "asynchronous" is false, will return the search results, otherwise returns null on bad input or if running in asynchronous mode.</returns> public static FRResults FindTargetInFiles(ASResult target, FRProgressReportHandler progressReportHandler, FRFinishedHandler findFinishedHandler, Boolean asynchronous) { Boolean currentFileOnly = false; // checks target is a member if (target == null || ((target.Member == null || String.IsNullOrEmpty(target.Member.Name)) && (target.Type == null || !CheckFlag(target.Type.Flags, FlagType.Class) && !target.Type.IsEnum()))) { return null; } else { // if the target we are trying to rename exists as a local variable or a function parameter we only need to search the current file if (target.Member != null && ( target.Member.Access == Visibility.Private || RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.LocalVar) || RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.ParameterVar)) ) { currentFileOnly = true; } } FRConfiguration config; IProject project = PluginBase.CurrentProject; String file = PluginBase.MainForm.CurrentDocument.FileName; // This is out of the project, just look for this file... if (currentFileOnly || !IsProjectRelatedFile(project, file)) { String mask = Path.GetFileName(file); String path = Path.GetDirectoryName(file); if (mask.Contains("[model]")) { if (findFinishedHandler != null) { findFinishedHandler(new FRResults()); } return null; } config = new FRConfiguration(path, mask, false, GetFRSearch(target.Member != null ? target.Member.Name : target.Type.Name)); } else if (target.Member != null && !CheckFlag(target.Member.Flags, FlagType.Constructor)) { config = new FRConfiguration(GetAllProjectRelatedFiles(project), GetFRSearch(target.Member.Name)); } else { target.Member = null; config = new FRConfiguration(GetAllProjectRelatedFiles(project), GetFRSearch(target.Type.Name)); } config.CacheDocuments = true; FRRunner runner = new FRRunner(); if (progressReportHandler != null) { runner.ProgressReport += progressReportHandler; } if (findFinishedHandler != null) { runner.Finished += findFinishedHandler; } if (asynchronous) runner.SearchAsync(config); else return runner.SearchSync(config); return null; }
public StatementReturnType(ASResult resolve, Int32 position, String word) { this.resolve = resolve; this.position = position; this.word = word; }
private static List<FunctionParameter> ParseFunctionParameters(ScintillaNet.ScintillaControl Sci, int p) { List<FunctionParameter> prms = new List<FunctionParameter>(); StringBuilder sb = new StringBuilder(); List<ASResult> types = new List<ASResult>(); bool isFuncStarted = false; bool isDoubleQuote = false; bool isSingleQuote = false; bool wasEscapeChar = false; bool doBreak = false; bool writeParam = false; int subClosuresCount = 0; ASResult result = null; IASContext ctx = ASContext.Context; char[] charsToTrim = new char[] { ' ', '\t', '\r', '\n' }; int counter = Sci.TextLength; // max number of chars in parameters line (to avoid infinitive loop) string characterClass = ScintillaNet.ScintillaControl.Configuration.GetLanguage(Sci.ConfigurationLanguage).characterclass.Characters; int lastMemberPos = p; // add [] and <> while (p < counter && !doBreak) { char c = (char)Sci.CharAt(p++); if (c == '(' && !isFuncStarted) { if (sb.ToString().Trim(charsToTrim).Length == 0) { isFuncStarted = true; } else { break; } } else if (c == ';' && !isFuncStarted) { break; } else if (c == ')' && isFuncStarted && !wasEscapeChar && !isDoubleQuote && !isSingleQuote && subClosuresCount == 0) { isFuncStarted = false; writeParam = true; doBreak = true; } else if ((c == '(' || c == '[' || c == '<' || c == '{') && !wasEscapeChar && !isDoubleQuote && !isSingleQuote) { if (subClosuresCount == 0) { if (c == '{') { if (sb.ToString().TrimStart().Length > 0) { result = new ASResult(); result.Type = ctx.ResolveType("Function", null); types.Insert(0, result); } else { result = new ASResult(); result.Type = ctx.ResolveType(ctx.Features.objectKey, null); types.Insert(0, result); } } else if (c == '(') { result = ASComplete.GetExpressionType(Sci, lastMemberPos + 1); if (!result.IsNull()) { types.Insert(0, result); } } else if (c == '<') { if (sb.ToString().TrimStart().Length == 0) { result = new ASResult(); result.Type = ctx.ResolveType("XML", null); types.Insert(0, result); } } } subClosuresCount++; sb.Append(c); wasEscapeChar = false; } else if ((c == ')' || c == ']' || c == '>' || c == '}') && !wasEscapeChar && !isDoubleQuote && !isSingleQuote) { if (c == ']') { result = ASComplete.GetExpressionType(Sci, p); if (result.Type != null) result.Member = null; else result.Type = ctx.ResolveType(ctx.Features.arrayKey, null); types.Insert(0, result); writeParam = true; } subClosuresCount--; sb.Append(c); wasEscapeChar = false; } else if (c == '\\') { wasEscapeChar = !wasEscapeChar; sb.Append(c); } else if (c == '"' && !wasEscapeChar && !isSingleQuote) { isDoubleQuote = !isDoubleQuote; if (subClosuresCount == 0) { if (isDoubleQuote) { result = new ASResult(); result.Type = ctx.ResolveType("String", null); types.Add(result); } } sb.Append(c); wasEscapeChar = false; } else if (c == '\'' && !wasEscapeChar && !isDoubleQuote) { isSingleQuote = !isSingleQuote; if (subClosuresCount == 0) { if (isSingleQuote) { result = new ASResult(); result.Type = ctx.ResolveType("String", null); types.Add(result); } } sb.Append(c); wasEscapeChar = false; } else if (c == ',' && subClosuresCount == 0) { if (!isSingleQuote && !isDoubleQuote && subClosuresCount == 0) { writeParam = true; } else { sb.Append(c); } wasEscapeChar = false; } else if (isFuncStarted) { sb.Append(c); if (!isSingleQuote && !isDoubleQuote && subClosuresCount == 0 && characterClass.IndexOf(c) > -1) { lastMemberPos = p - 1; } wasEscapeChar = false; } else if (characterClass.IndexOf(c) > -1) { doBreak = true; } if (writeParam) { writeParam = false; string trimmed = sb.ToString().Trim(charsToTrim); if (trimmed.Length > 0) { result = ASComplete.GetExpressionType(Sci, lastMemberPos + 1); if (result != null && !result.IsNull()) { if (characterClass.IndexOf(trimmed[trimmed.Length - 1]) > -1) { types.Insert(0, result); } else { types.Add(result); } } else { double d = double.MaxValue; try { d = double.Parse(trimmed, System.Globalization.CultureInfo.InvariantCulture); } catch (Exception) { } if (d != double.MaxValue && d.ToString().Length == trimmed.Length) { result = new ASResult(); result.Type = ctx.ResolveType(ctx.Features.numberKey, null); types.Insert(0, result); } else if (trimmed.Equals("true") || trimmed.Equals("false")) { result = new ASResult(); result.Type = ctx.ResolveType(ctx.Features.booleanKey, null); types.Insert(0, result); } } if (types.Count == 0) { result = new ASResult(); result.Type = ctx.ResolveType(ctx.Features.objectKey, null); types.Add(result); } result = types[0]; string paramName = null; string paramType = null; string paramQualType = null; if (result.Member == null) { paramType = result.Type.Name; paramQualType = result.Type.QualifiedName; } else { if (result.Member.Name != null) { paramName = result.Member.Name.Trim('@'); } if (result.Member.Type == null || result.Member.Type.Equals("void", StringComparison.OrdinalIgnoreCase)) { paramType = result.Type.Name; paramQualType = result.Type.QualifiedName; } else { paramType = FormatType(GetShortType(result.Member.Type)); if (result.InClass == null) { paramQualType = result.Type.QualifiedName; } else { paramQualType = getQualifiedType(result.Member.Type, result.InClass); } } } prms.Add(new FunctionParameter(paramName, paramType, paramQualType, result)); } types = new List<ASResult>(); sb = new StringBuilder(); } } for (int i = 0; i < prms.Count; i++) { if (prms[i].paramType == "void") { prms[i].paramName = "object"; prms[i].paramType = null; } else prms[i].paramName = GuessVarName(prms[i].paramName, FormatType(GetShortType(prms[i].paramType))); } for (int i = 0; i < prms.Count; i++) { int iterator = -1; bool nameUnique = false; string name = prms[i].paramName; string suggestedName = name; while (!nameUnique) { iterator++; suggestedName = name + (iterator == 0 ? "" : iterator + ""); bool gotMatch = false; for (int j = 0; j < i; j++) { if (prms[j] != prms[i] && prms[j].paramName == suggestedName) { gotMatch = true; break; } } nameUnique = !gotMatch; } prms[i].paramName = suggestedName; } return prms; }
/// <summary> /// Top-level elements lookup /// </summary> /// <param name="token">Element to search</param> /// <param name="result">Response structure</param> public override void ResolveTopLevelElement(string token, ASResult result) { if (topLevel != null && topLevel.Members.Count > 0) { // current class ClassModel inClass = ASContext.Context.CurrentClass; if (token == "this") { result.Member = topLevel.Members.Search("this", 0, 0); if (inClass.IsVoid()) inClass = ASContext.Context.ResolveType(result.Member.Type, null); result.Type = inClass; result.InFile = ASContext.Context.CurrentModel; return; } else if (token == "super") { if (inClass.IsVoid()) { MemberModel thisMember = topLevel.Members.Search("this", 0, 0); inClass = ASContext.Context.ResolveType(thisMember.Type, null); } inClass.ResolveExtends(); ClassModel extends = inClass.Extends; if (!extends.IsVoid()) { result.Member = topLevel.Members.Search("super", 0, 0); result.Type = extends; result.InFile = extends.InFile; return; } } // other top-level elements ASComplete.FindMember(token, topLevel, result, 0, 0); if (!result.IsNull()) return; // special _levelN if (hasLevels && token.StartsWith("_") && re_level.IsMatch(token)) { result.Member = new MemberModel(); result.Member.Name = token; result.Member.Flags = FlagType.Variable; result.Member.Type = "MovieClip"; result.Type = ResolveType("MovieClip", null); result.InFile = topLevel; } } }
/// <summary> /// Finds the given target in all project files. /// If the target is a local variable or function parameter, it will only search the associated file. /// Note: if running asynchronously, you must supply a listener to "findFinishedHandler" to retrieve the results. /// If running synchronously, do not set listeners and instead use the return value. /// </summary> /// <param name="target">the source member to find references to</param> /// <param name="progressReportHandler">event to fire as search results are compiled</param> /// <param name="findFinishedHandler">event to fire once searching is finished</param> /// <param name="asynchronous">executes in asynchronous mode</param> /// <param name="onlySourceFiles">searches only on defined classpaths</param> /// <returns>If "asynchronous" is false, will return the search results, otherwise returns null on bad input or if running in asynchronous mode.</returns> public static FRResults FindTargetInFiles(ASResult target, FRProgressReportHandler progressReportHandler, FRFinishedHandler findFinishedHandler, Boolean asynchronous, Boolean onlySourceFiles, Boolean ignoreSdkFiles) { return(FindTargetInFiles(target, progressReportHandler, findFinishedHandler, asynchronous, onlySourceFiles, ignoreSdkFiles, false, false)); }
/// <summary> /// Checks if a given search match actually points to the given target source /// </summary> /// <returns>True if the SearchMatch does point to the target source.</returns> public static bool DoesMatchPointToTarget(ScintillaControl Sci, SearchMatch match, ASResult target, DocumentHelper associatedDocumentHelper) { if (Sci == null || target == null) { return(false); } FileModel targetInFile = null; if (target.InFile != null) { targetInFile = target.InFile; } else if (target.Member != null && target.InClass == null) { targetInFile = target.Member.InFile; } Boolean matchMember = targetInFile != null && target.Member != null; Boolean matchType = target.Member == null && target.IsStatic && target.Type != null; if (!matchMember && !matchType) { return(false); } ASResult result = null; // get type at match position if (match.Index < Sci.Text.Length) // TODO: find out rare cases of incorrect index reported { result = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); if (associatedDocumentHelper != null) { // because the declaration lookup opens a document, we should register it with the document helper to be closed later associatedDocumentHelper.RegisterLoadedDocument(PluginBase.MainForm.CurrentDocument); } } // check if the result matches the target if (result == null || (result.InFile == null && result.Type == null)) { return(false); } if (matchMember) { if (result.Member == null) { return(false); } var resultInFile = result.InClass != null ? result.InFile : result.Member.InFile; return(resultInFile.BasePath == targetInFile.BasePath && resultInFile.FileName == targetInFile.FileName && result.Member.LineFrom == target.Member.LineFrom && result.Member.Name == target.Member.Name); } else // type { if (result.Type == null) { return(false); } if (result.Type.QualifiedName == target.Type.QualifiedName) { return(true); } return(false); } }
public static string GetRefactorTargetName(ASResult target) { return(GetRefactoringTarget(target).Name); }
/** * Handles the incoming events */ public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority priority) { try { // ignore all events when leaving if (PluginBase.MainForm.ClosingEntirely) { return; } // current active document ITabbedDocument doc = PluginBase.MainForm.CurrentDocument; // application start if (!started && e.Type == EventType.UIStarted) { started = true; PathExplorer.OnUIStarted(); // associate context to initial document e = new NotifyEvent(EventType.SyntaxChange); this.pluginUI.UpdateAfterTheme(); } // editor ready? if (doc == null) { return; } ScintillaControl sci = doc.IsEditable ? doc.SciControl : null; // // Events always handled // bool isValid; DataEvent de; switch (e.Type) { // caret position in editor case EventType.UIRefresh: if (!doc.IsEditable) { return; } timerPosition.Enabled = false; timerPosition.Enabled = true; return; // key combinations case EventType.Keys: Keys key = (e as KeyEvent).Value; if (ModelsExplorer.HasFocus) { e.Handled = ModelsExplorer.Instance.OnShortcut(key); return; } if (!doc.IsEditable) { return; } e.Handled = ASComplete.OnShortcut(key, sci); return; // user-customized shortcuts case EventType.Shortcut: de = e as DataEvent; if (de.Action == "Completion.ShowHelp") { ASComplete.HelpKeys = (Keys)de.Data; de.Handled = true; } return; // // File management // case EventType.FileSave: if (!doc.IsEditable) { return; } ASContext.Context.CheckModel(false); // toolbar isValid = ASContext.Context.IsFileValid; if (isValid && !PluginBase.MainForm.SavingMultiple) { if (ASContext.Context.Settings.CheckSyntaxOnSave) { CheckSyntax(null, null); } ASContext.Context.RemoveClassCompilerCache(); } return; case EventType.SyntaxDetect: // detect Actionscript language version if (!doc.IsEditable) { return; } if (doc.FileName.ToLower().EndsWith(".as")) { settingObject.LastASVersion = DetectActionscriptVersion(doc); (e as TextEvent).Value = settingObject.LastASVersion; e.Handled = true; } break; case EventType.ApplySettings: case EventType.SyntaxChange: case EventType.FileSwitch: if (!doc.IsEditable) { ASContext.SetCurrentFile(null, true); ContextChanged(); return; } currentDoc = doc.FileName; currentPos = sci.CurrentPos; // check file bool ignoreFile = !doc.IsEditable; ASContext.SetCurrentFile(doc, ignoreFile); // UI ContextChanged(); return; case EventType.Completion: if (ASContext.Context.IsFileValid) { e.Handled = true; } return; // some commands work all the time case EventType.Command: de = e as DataEvent; string command = de.Action ?? ""; if (command.StartsWith("ASCompletion.")) { string cmdData = de.Data as string; // add a custom classpath if (command == "ASCompletion.ClassPath") { Hashtable info = de.Data as Hashtable; if (info != null) { ContextSetupInfos setup = new ContextSetupInfos(); setup.Platform = (string)info["platform"]; setup.Lang = (string)info["lang"]; setup.Version = (string)info["version"]; setup.TargetBuild = (string)info["targetBuild"]; setup.Classpath = (string[])info["classpath"]; setup.HiddenPaths = (string[])info["hidden"]; ASContext.SetLanguageClassPath(setup); if (setup.AdditionalPaths != null) // report custom classpath { info["additional"] = setup.AdditionalPaths.ToArray(); } } e.Handled = true; } // send a UserClasspath else if (command == "ASCompletion.GetUserClasspath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null && context.Settings != null && context.Settings.UserClasspath != null) { info["cp"] = new List <string>(context.Settings.UserClasspath); } } e.Handled = true; } // update a UserClasspath else if (command == "ASCompletion.SetUserClasspath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language") && info.ContainsKey("cp")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); List <string> cp = info["cp"] as List <string>; if (cp != null && context != null && context.Settings != null) { string[] pathes = new string[cp.Count]; cp.CopyTo(pathes); context.Settings.UserClasspath = pathes; } } e.Handled = true; } // send the language's default compiler path else if (command == "ASCompletion.GetCompilerPath") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null) { info["compiler"] = context.GetCompilerPath(); } } e.Handled = true; } // show a language's compiler settings else if (command == "ASCompletion.ShowSettings") { e.Handled = true; IASContext context = ASContext.GetLanguageContext(cmdData); if (context == null) { return; } string filter = "SDK"; string name = ""; switch (cmdData.ToUpper()) { case "AS2": name = "AS2Context"; break; case "AS3": name = "AS3Context"; break; default: name = cmdData.Substring(0, 1).ToUpper() + cmdData.Substring(1) + "Context"; break; } PluginBase.MainForm.ShowSettingsDialog(name, filter); } // Open types explorer dialog else if (command == "ASCompletion.TypesExplorer") { TypesExplorer(null, null); } // call the Flash IDE else if (command == "ASCompletion.CallFlashIDE") { if (flashErrorsWatcher == null) { flashErrorsWatcher = new FlashErrorsWatcher(); } e.Handled = CallFlashIDE.Run(settingObject.PathToFlashIDE, cmdData); } // create Flash 8+ trust file else if (command == "ASCompletion.CreateTrustFile") { if (cmdData != null) { string[] args = cmdData.Split(';'); if (args.Length == 2) { e.Handled = CreateTrustFile.Run(args[0], args[1]); } } } else if (command == "ASCompletion.GetClassPath") { if (cmdData != null) { string[] args = cmdData.Split(';'); if (args.Length == 1) { FileModel model = ASContext.Context.GetFileModel(args[0]); ClassModel aClass = model.GetPublicClass(); if (!aClass.IsVoid()) { Clipboard.SetText(aClass.QualifiedName); e.Handled = true; } } } } else if (command == "ProjectManager.FileActions.DisableWatchers") { foreach (PathModel cp in ASContext.Context.Classpath) { cp.DisableWatcher(); } } else if (command == "ProjectManager.FileActions.EnableWatchers") { // classpaths could be invalid now - remove those, BuildClassPath() is too expensive ASContext.Context.Classpath.RemoveAll(cp => !Directory.Exists(cp.Path)); foreach (PathModel cp in ASContext.Context.Classpath) { cp.EnableWatcher(); } } // Return requested language SDK list else if (command == "ASCompletion.InstalledSDKs") { Hashtable info = de.Data as Hashtable; if (info != null && info.ContainsKey("language")) { IASContext context = ASContext.GetLanguageContext(info["language"] as string); if (context != null) { info["sdks"] = context.Settings.InstalledSDKs; } } e.Handled = true; } } // Create a fake document from a FileModel else if (command == "ProjectManager.OpenVirtualFile") { string cmdData = de.Data as string; if (reVirtualFile.IsMatch(cmdData)) { string[] path = Regex.Split(cmdData, "::"); string fileName = path[0] + Path.DirectorySeparatorChar + path[1].Replace('.', Path.DirectorySeparatorChar).Replace("::", Path.DirectorySeparatorChar.ToString()); FileModel found = ModelsExplorer.Instance.OpenFile(fileName); if (found != null) { e.Handled = true; } } } else if (command == "ProjectManager.UserRefreshTree") { ASContext.UserRefreshRequestAll(); } break; } // // Actionscript context specific // if (ASContext.Context.IsFileValid) { switch (e.Type) { case EventType.ProcessArgs: TextEvent te = (TextEvent)e; if (reArgs.IsMatch(te.Value)) { // resolve current element Hashtable details = ASComplete.ResolveElement(sci, null); te.Value = ArgumentsProcessor.Process(te.Value, details); if (te.Value.IndexOf("$") >= 0 && reCostlyArgs.IsMatch(te.Value)) { ASResult result = ASComplete.CurrentResolvedContext.Result ?? new ASResult(); details = new Hashtable(); // Get closest list (Array or Vector) string closestListName = "", closestListItemType = ""; ASComplete.FindClosestList(ASContext.Context, result.Context, sci.CurrentLine, ref closestListName, ref closestListItemType); details.Add("TypClosestListName", closestListName); details.Add("TypClosestListItemType", closestListItemType); // get free iterator index string iterator = ASComplete.FindFreeIterator(ASContext.Context, ASContext.Context.CurrentClass, result.Context); details.Add("ItmUniqueVar", iterator); te.Value = ArgumentsProcessor.Process(te.Value, details); } } break; // menu commands case EventType.Command: string command = (e as DataEvent).Action ?? ""; if (command.StartsWith("ASCompletion.")) { string cmdData = (e as DataEvent).Data as string; // run MTASC if (command == "ASCompletion.CustomBuild") { if (cmdData != null) { ASContext.Context.RunCMD(cmdData); } else { ASContext.Context.RunCMD(""); } e.Handled = true; } // build the SWF using MTASC else if (command == "ASCompletion.QuickBuild") { ASContext.Context.BuildCMD(false); e.Handled = true; } // resolve element under cusor and open declaration else if (command == "ASCompletion.GotoDeclaration") { ASComplete.DeclarationLookup(sci); e.Handled = true; } // resolve element under cursor and send a CustomData event else if (command == "ASCompletion.ResolveElement") { ASComplete.ResolveElement(sci, cmdData); e.Handled = true; } else if (command == "ASCompletion.MakeIntrinsic") { ASContext.Context.MakeIntrinsic(cmdData); e.Handled = true; } // alternative to default shortcuts else if (command == "ASCompletion.CtrlSpace") { ASComplete.OnShortcut(Keys.Control | Keys.Space, ASContext.CurSciControl); e.Handled = true; } else if (command == "ASCompletion.CtrlShiftSpace") { ASComplete.OnShortcut(Keys.Control | Keys.Shift | Keys.Space, ASContext.CurSciControl); e.Handled = true; } else if (command == "ASCompletion.CtrlAltSpace") { ASComplete.OnShortcut(Keys.Control | Keys.Alt | Keys.Space, ASContext.CurSciControl); e.Handled = true; } else if (command == "ASCompletion.ContextualGenerator") { if (ASContext.HasContext && ASContext.Context.IsFileValid) { ASGenerator.ContextualGenerator(ASContext.CurSciControl); } } } return; case EventType.ProcessEnd: string procResult = (e as TextEvent).Value; ASContext.Context.OnProcessEnd(procResult); break; } } } catch (Exception ex) { ErrorManager.ShowError(ex); } }
/// <inheritdoc /> public virtual Command CreateFindAllReferencesCommand(ASResult target, bool output, bool ignoreDeclarations) { return(CreateFindAllReferencesCommand(target, output, ignoreDeclarations, true)); }
/// <inheritdoc /> public virtual Command CreateFindAllReferencesCommand(ASResult target, bool output) { return(CreateFindAllReferencesCommand(target, output, false)); }
public virtual DelegateMethodsCommand CreateDelegateMethodsCommand(ASResult result, Dictionary <MemberModel, ClassModel> selectedMembers) { return(new DelegateMethodsCommand(result, selectedMembers)); }
/// <summary> /// Top-level elements lookup /// </summary> /// <param name="token">Element to search</param> /// <param name="result">Response structure</param> public override void ResolveTopLevelElement(string token, ASResult result) { if (topLevel != null && topLevel.Members.Count > 0) { // current class ClassModel inClass = ASContext.Context.CurrentClass; if (token == "this") { result.Member = topLevel.Members.Search("this", 0, 0); if (inClass.IsVoid()) inClass = ASContext.Context.ResolveType(result.Member.Type, null); result.Type = inClass; result.InFile = ASContext.Context.CurrentModel; return; } else if (token == "super") { if (inClass.IsVoid()) { MemberModel thisMember = topLevel.Members.Search("this", 0, 0); inClass = ASContext.Context.ResolveType(thisMember.Type, null); } inClass.ResolveExtends(); ClassModel extends = inClass.Extends; if (!extends.IsVoid()) { result.Member = topLevel.Members.Search("super", 0, 0); result.Type = extends; result.InFile = extends.InFile; return; } } } }
/// <summary> /// Resolve the class and member at the provided line index /// </summary> /// <param name="line"></param> /// <returns></returns> public virtual ASResult GetDeclarationAtLine(int line) { ASResult result = new ASResult(); result.InClass = ClassModel.VoidClass; if (cFile == null) return result; // current class foreach (ClassModel aClass in cFile.Classes) { if (aClass.LineFrom <= line && aClass.LineTo >= line) { result.InClass = aClass; // current member foreach (MemberModel member in result.InClass.Members) { if (member.LineFrom <= line && member.LineTo >= line) { result.Member = member; return result; } else if (member.LineFrom > line) return result; } return result; } } // current member foreach (MemberModel member in cFile.Members) { if (member.LineFrom <= line && member.LineTo >= line) { result.Member = member; return result; } else if (member.LineFrom > line) return result; } return result; }
/// <summary> /// Updates the state of the menu items /// </summary> private void UpdateMenuItems() { try { this.refactorMainMenu.DelegateMenuItem.Enabled = false; this.refactorContextMenu.DelegateMenuItem.Enabled = false; bool langIsValid = GetLanguageIsValid(); ResolvedContext resolved = ASComplete.CurrentResolvedContext; bool isValid = langIsValid && resolved != null && resolved.Position >= 0; ASResult result = isValid ? resolved.Result : null; if (result != null && !result.IsNull()) { bool isNotPackage = !result.IsPackage; this.refactorContextMenu.RenameMenuItem.Enabled = true; this.refactorMainMenu.RenameMenuItem.Enabled = true; this.editorReferencesItem.Enabled = isNotPackage; this.viewReferencesItem.Enabled = isNotPackage; if (result.Member != null && result.Type != null && result.InClass != null && result.InFile != null) { FlagType flags = result.Member.Flags; if ((flags & FlagType.Variable) > 0 && (flags & FlagType.LocalVar) == 0 && (flags & FlagType.ParameterVar) == 0) { this.refactorContextMenu.DelegateMenuItem.Enabled = true; this.refactorMainMenu.DelegateMenuItem.Enabled = true; } } } else { this.refactorMainMenu.RenameMenuItem.Enabled = false; this.refactorContextMenu.RenameMenuItem.Enabled = false; this.editorReferencesItem.Enabled = false; this.viewReferencesItem.Enabled = false; } IASContext context = ASContext.Context; if (context != null && context.CurrentModel != null) { bool truncate = (langIsValid && context.CurrentModel.Imports.Count > 0) && !this.LanguageIsHaxe(); bool organize = (langIsValid && context.CurrentModel.Imports.Count > 1); this.refactorContextMenu.OrganizeMenuItem.Enabled = organize; this.refactorContextMenu.TruncateMenuItem.Enabled = truncate; this.refactorMainMenu.OrganizeMenuItem.Enabled = organize; this.refactorMainMenu.TruncateMenuItem.Enabled = truncate; } this.surroundContextMenu.Enabled = false; this.refactorMainMenu.SurroundMenu.Enabled = false; this.refactorContextMenu.ExtractMethodMenuItem.Enabled = false; this.refactorContextMenu.ExtractLocalVariableMenuItem.Enabled = false; this.refactorMainMenu.ExtractMethodMenuItem.Enabled = false; this.refactorMainMenu.ExtractLocalVariableMenuItem.Enabled = false; ITabbedDocument document = PluginBase.MainForm.CurrentDocument; if (document != null && document.IsEditable && langIsValid && document.SciControl.SelTextSize > 1) { Int32 selEnd = document.SciControl.SelectionEnd; Int32 selStart = document.SciControl.SelectionStart; if (!document.SciControl.PositionIsOnComment(selEnd) || !document.SciControl.PositionIsOnComment(selStart)) { this.surroundContextMenu.Enabled = true; this.refactorMainMenu.SurroundMenu.Enabled = true; this.refactorContextMenu.ExtractMethodMenuItem.Enabled = true; this.refactorMainMenu.ExtractMethodMenuItem.Enabled = true; this.refactorContextMenu.ExtractLocalVariableMenuItem.Enabled = true; this.refactorMainMenu.ExtractLocalVariableMenuItem.Enabled = true; } } this.refactorContextMenu.CodeGeneratorMenuItem.Enabled = isValid; this.refactorMainMenu.CodeGeneratorMenuItem.Enabled = isValid; } catch {} }
public DelegateMethodsCommand(ASResult result, Dictionary<MemberModel, ClassModel> selectedMembers) { this.result = result; this.selectedMembers = selectedMembers; }
public static bool GotoDeclaration() { ScintillaNet.ScintillaControl sci = PluginBase.MainForm.CurrentDocument.SciControl; if (sci == null) { return(false); } if (sci.ConfigurationLanguage != "xml") { return(false); } int pos = sci.CurrentPos; int len = sci.TextLength; while (pos < len) { char c = (char)sci.CharAt(pos); if (c <= 32 || c == '/' || c == '>') { break; } pos++; } XMLContextTag ctag = XMLComplete.GetXMLContextTag(sci, pos); if (ctag.Name == null) { return(true); } string word = sci.GetWordFromPosition(sci.CurrentPos); string type = ResolveType(mxmlContext, ctag.Name); ClassModel model = context.ResolveType(type, mxmlContext.model); if (model.IsVoid()) // try resolving tag as member of parent tag { parentTag = XMLComplete.GetParentTag(sci, ctag); if (parentTag.Name != null) { ctag = parentTag; type = ResolveType(mxmlContext, ctag.Name); model = context.ResolveType(type, mxmlContext.model); if (model.IsVoid()) { return(true); } } else { return(true); } } if (!ctag.Name.EndsWith(word)) { ASResult found = ResolveAttribute(model, word); ASComplete.OpenDocumentToDeclaration(sci, found); } else { ASResult found = new ASResult(); found.InFile = model.InFile; found.Type = model; ASComplete.OpenDocumentToDeclaration(sci, found); } return(true); }
private static void GenerateImplementation(ClassModel aType, int position) { List<string> typesUsed = new List<string>(); StringBuilder sb = new StringBuilder(TemplateUtils.ReplaceTemplateVariable(TemplateUtils.GetTemplate("ImplementHeader"), "Class", aType.Type)); sb.Append(NewLine); bool entry = true; ASResult result = new ASResult(); IASContext context = ASContext.Context; ClassModel cClass = context.CurrentClass; ContextFeatures features = context.Features; bool canGenerate = false; aType.ResolveExtends(); // resolve inheritance chain while (!aType.IsVoid() && aType.QualifiedName != "Object") { foreach (MemberModel method in aType.Members) { if ((method.Flags & (FlagType.Function | FlagType.Getter | FlagType.Setter)) == 0 || method.Name == aType.Name) continue; // check if method exists ASComplete.FindMember(method.Name, cClass, result, method.Flags, 0); if (!result.IsNull()) continue; string decl = entry ? NewLine : ""; if ((method.Flags & FlagType.Getter) > 0) decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Getter")); else if ((method.Flags & FlagType.Setter) > 0) decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Setter")); else decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Function")); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Member", "_" + method.Name); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Void", features.voidKey); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Body", null); decl = TemplateUtils.ReplaceTemplateVariable(decl, "BlankLine", NewLine); if (!entry) { decl = TemplateUtils.ReplaceTemplateVariable(decl, "EntryPoint", null); } decl += NewLine; entry = false; sb.Append(decl); canGenerate = true; addTypeOnce(typesUsed, getQualifiedType(method.Type, aType)); if (method.Parameters != null && method.Parameters.Count > 0) foreach (MemberModel param in method.Parameters) addTypeOnce(typesUsed, getQualifiedType(param.Type, aType)); } // interface inheritance aType = aType.Extends; } if (!canGenerate) return; ScintillaNet.ScintillaControl Sci = ASContext.CurSciControl; Sci.BeginUndoAction(); try { position = Sci.CurrentPos; if (ASContext.Context.Settings.GenerateImports && typesUsed.Count > 0) { int offset = AddImportsByName(typesUsed, Sci.LineFromPosition(position)); position += offset; Sci.SetSel(position, position); } InsertCode(position, sb.ToString()); } finally { Sci.EndUndoAction(); } }
static bool IsObject(ASResult collection) { var type = collection.Member?.Type; return(!string.IsNullOrEmpty(type) && type == ASContext.Context.Features.objectKey); }
private static void ShowGetSetList(FoundDeclaration found) { string name = GetPropertyNameFor(found.member); ASResult result = new ASResult(); ClassModel curClass = ASContext.Context.CurrentClass; ASComplete.FindMember(name, curClass, result, FlagType.Getter, 0); bool hasGetter = !result.IsNull(); ASComplete.FindMember(name, curClass, result, FlagType.Setter, 0); bool hasSetter = !result.IsNull(); if (hasGetter && hasSetter) return; List<ICompletionListItem> known = new List<ICompletionListItem>(); if (!hasGetter && !hasSetter) { string label = TextHelper.GetString("ASCompletion.Label.GenerateGetSet"); known.Add(new GeneratorItem(label, GeneratorJobType.GetterSetter, found.member, found.inClass)); } if (!hasGetter) { string label = TextHelper.GetString("ASCompletion.Label.GenerateGet"); known.Add(new GeneratorItem(label, GeneratorJobType.Getter, found.member, found.inClass)); } if (!hasSetter) { string label = TextHelper.GetString("ASCompletion.Label.GenerateSet"); known.Add(new GeneratorItem(label, GeneratorJobType.Setter, found.member, found.inClass)); } CompletionList.Show(known, false); }
/// <summary> /// Checks if a given search match actually points to the given target source /// </summary /// <returns>True if the SearchMatch does point to the target source.</returns> static public bool DoesMatchPointToTarget(ScintillaNet.ScintillaControl Sci, SearchMatch match, ASResult target, DocumentHelper associatedDocumentHelper) { if (Sci == null || target == null || target.inFile == null || target.Member == null) { return false; } // get type at match position ASResult result = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); if (associatedDocumentHelper != null) { // because the declaration lookup opens a document, we should register it with the document helper to be closed later associatedDocumentHelper.RegisterLoadedDocument(PluginBase.MainForm.CurrentDocument); } // check if the result matches the target // TODO: this method of checking their equality seems pretty crude -- is there a better way? if (result == null || result.inFile == null || result.Member == null) { return false; } Boolean doesMatch = result.inFile.BasePath == target.inFile.BasePath && result.inFile.FileName == target.inFile.FileName && result.Member.LineFrom == target.Member.LineFrom && result.Member.Name == target.Member.Name; return (doesMatch); }
private void RenameFile(IDictionary <string, List <SearchMatch> > results) { ASResult target = findAllReferencesCommand.CurrentTarget; Boolean isEnum = target.Type.IsEnum(); Boolean isClass = false; Boolean isConstructor = false; if (!isEnum) { Boolean isVoid = target.Type.IsVoid(); isClass = !isVoid && target.IsStatic && target.Member == null; isConstructor = !isVoid && !isClass && RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.Constructor); } Boolean isGlobalFunction = false; Boolean isGlobalNamespace = false; if (!isEnum && !isClass && !isConstructor && (target.InClass == null || target.InClass.IsVoid())) { isGlobalFunction = RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.Function); isGlobalNamespace = RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.Namespace); } if (!isEnum && !isClass && !isConstructor && !isGlobalFunction && !isGlobalNamespace) { return; } FileModel inFile = null; String originName = null; if (isEnum || isClass) { inFile = target.Type.InFile; originName = target.Type.Name; } else { inFile = target.Member.InFile; originName = target.Member.Name; } if (inFile == null) { return; } String oldFileName = inFile.FileName; String oldName = Path.GetFileNameWithoutExtension(oldFileName); if (!string.IsNullOrEmpty(oldName) && !oldName.Equals(originName)) { return; } String fullPath = Path.GetFullPath(inFile.FileName); fullPath = Path.GetDirectoryName(fullPath); String newFileName = Path.Combine(fullPath, NewName + Path.GetExtension(oldFileName)); if (string.IsNullOrEmpty(oldFileName) || oldFileName.Equals(newFileName)) { return; } foreach (ITabbedDocument doc in PluginBase.MainForm.Documents) { if (doc.FileName.Equals(oldFileName)) { doc.Save(); doc.Close(); break; } } RefactoringHelper.Move(oldFileName, newFileName); AssociatedDocumentHelper.LoadDocument(newFileName); if (results.ContainsKey(oldFileName)) { results[newFileName] = results[oldFileName]; results.Remove(oldFileName); } }
public virtual Command CreateRenameCommandAndExecute(ASResult target, bool outputResults, string newName, bool inline = false) { return(CreateRenameCommandAndExecute(target, outputResults, newName, false, inline)); }
public static void AddToQueue(ASResult target) { AddToQueue(target, true); }
/// <summary> /// A new Rename refactoring command. /// </summary> /// <param name="target">The target declaration to find references to.</param> /// <param name="outputResults">If true, will send the found results to the trace log and results panel</param> public Rename(ASResult target, Boolean outputResults) : this(target, outputResults, null) { }
/// <summary> /// A new Rename refactoring command. /// </summary> /// <param name="target">The target declaration to find references to.</param> /// <param name="outputResults">If true, will send the found results to the trace log and results panel</param> /// <param name="newName">If provided, will not query the user for a new name.</param> public Rename(ASResult target, Boolean outputResults, String newName) : this(target, outputResults, newName, false) { }
public DelegateMethodsCommand(ASResult result, Dictionary <MemberModel, ClassModel> selectedMembers) { this.result = result; this.selectedMembers = selectedMembers; }
public static string GetRefactorTargetName(ASResult target) { return GetRefactoringTarget(target).Name; }
/// <summary> /// Removes the highlights from the correct sci control /// </summary> private void RemoveHighlights(ScintillaControl sci) { if (sci != null) { int es = sci.EndStyled; int mask = 1 << sci.StyleBits; sci.StartStyling(0, mask); sci.SetStyling(sci.TextLength, 0); sci.StartStyling(es, mask - 1); if (settings.AddLineMarker) sci.MarkerDeleteAll(MARKER_NUMBER); } prevPos = -1; prevToken = string.Empty; prevResult = null; }
private static void GenerateImplementation(ClassModel aType, int position) { List<string> typesUsed = new List<string>(); StringBuilder sb = new StringBuilder(String.Format(GetTemplate("ImplementHeader"), aType.Type)); string entry = "$(EntryPoint)"; ASResult result = new ASResult(); IASContext context = ASContext.Context; ClassModel cClass = context.CurrentClass; ContextFeatures features = context.Features; bool canGenerate = false; string template = GetTemplate("ImplementPart"); aType.ResolveExtends(); // resolve inheritance chain while (!aType.IsVoid() && aType.QualifiedName != "Object") { foreach (MemberModel method in aType.Members) { if ((method.Flags & (FlagType.Function | FlagType.Getter | FlagType.Setter)) == 0 || method.Name == aType.Name) continue; // check if method exists ASComplete.FindMember(method.Name, cClass, result, method.Flags, 0); if (!result.IsNull()) continue; string decl = String.Format(template, GetDeclaration(method), entry); entry = ""; sb.Append(decl); canGenerate = true; addTypeOnce(typesUsed, getQualifiedType(method.Type, aType)); if (method.Parameters != null && method.Parameters.Count > 0) foreach (MemberModel param in method.Parameters) addTypeOnce(typesUsed, getQualifiedType(param.Type, aType)); } // interface inheritance aType = aType.Extends; } if (!canGenerate) return; ScintillaNet.ScintillaControl Sci = ASContext.CurSciControl; Sci.BeginUndoAction(); try { position = Sci.CurrentPos; if (ASContext.Context.Settings.GenerateImports && typesUsed.Count > 0) { int offset = AddImportsByName(typesUsed, Sci.LineFromPosition(position)); position += offset; Sci.SetSel(position, position); } InsertCode(position, sb.ToString()); } finally { Sci.EndUndoAction(); } }
/// <summary> /// /// </summary> private void UpdateHighlightUnderCursor(ScintillaControl sci) { string file = PluginBase.MainForm.CurrentDocument.FileName; if (!IsValidFile(file)) return; int currentPos = sci.CurrentPos; string newToken = sci.GetWordFromPosition(currentPos); if (!string.IsNullOrEmpty(newToken)) newToken = newToken.Trim(); if (!string.IsNullOrEmpty(newToken)) { if (prevResult == null && prevToken == newToken) return; ASResult result = IsValidFile(file) ? ASComplete.GetExpressionType(sci, sci.WordEndPosition(currentPos, true)) : null; if (result != null && !result.IsNull()) { if (prevResult != null && (result.Member != prevResult.Member || result.Type != prevResult.Type || result.Path != prevResult.Path)) return; RemoveHighlights(sci); prevToken = newToken; prevResult = result; List<SearchMatch> matches = FilterResults(GetResults(sci, prevToken), result, sci); if (matches == null || matches.Count == 0) return; highlightUnderCursorTimer.Stop(); AddHighlights(sci, matches); } else RemoveHighlights(sci); } else RemoveHighlights(sci); }
/// <summary> /// Finds the given target in all project files. /// If the target is a local variable or function parameter, it will only search the associated file. /// Note: if running asynchronously, you must supply a listener to "findFinishedHandler" to retrieve the results. /// If running synchronously, do not set listeners and instead use the return value. /// </summary> /// <param name="target">the source member to find references to</param> /// <param name="progressReportHandler">event to fire as search results are compiled</param> /// <param name="findFinishedHandler">event to fire once searching is finished</param> /// <param name="asynchronous">executes in asynchronous mode</param> /// <returns>If "asynchronous" is false, will return the search results, otherwise returns null on bad input or if running in asynchronous mode.</returns> public static FRResults FindTargetInFiles(ASResult target, FRProgressReportHandler progressReportHandler, FRFinishedHandler findFinishedHandler, Boolean asynchronous) { return FindTargetInFiles(target, progressReportHandler, findFinishedHandler, asynchronous, false, false); }
/// <summary> /// Filters the initial result set by determining which entries actually resolve back to our declaration target. /// </summary> private IDictionary <String, List <SearchMatch> > ResolveActualMatches(FRResults results, ASResult target) { // this will hold actual references back to the source member (some result hits could point to different members with the same name) IDictionary <String, List <SearchMatch> > actualMatches = new Dictionary <String, List <SearchMatch> >(); IDictionary <String, List <SearchMatch> > initialResultsList = RefactoringHelper.GetInitialResultsList(results); int matchesChecked = 0; int totalMatches = 0; foreach (KeyValuePair <String, List <SearchMatch> > entry in initialResultsList) { totalMatches += entry.Value.Count; } Boolean foundDeclarationSource = false; bool optionsEnabled = IncludeComments || IncludeStrings; foreach (KeyValuePair <String, List <SearchMatch> > entry in initialResultsList) { String currentFileName = entry.Key; UserInterfaceManager.ProgressDialog.UpdateStatusMessage(TextHelper.GetString("Info.ResolvingReferencesIn") + " \"" + currentFileName + "\""); foreach (SearchMatch match in entry.Value) { // we have to open/reopen the entry's file // there are issues with evaluating the declaration targets with non-open, non-current files // we have to do it each time as the process of checking the declaration source can change the currently open file! ScintillaControl sci = this.AssociatedDocumentHelper.LoadDocument(currentFileName).SciControl; // if the search result does point to the member source, store it bool add = false; if (RefactoringHelper.DoesMatchPointToTarget(sci, match, target, this.AssociatedDocumentHelper)) { if (ignoreDeclarationSource && !foundDeclarationSource && RefactoringHelper.IsMatchTheTarget(sci, match, target)) { //ignore the declaration source foundDeclarationSource = true; } else { add = true; } } else if (optionsEnabled) { add = RefactoringHelper.IsInsideCommentOrString(match, sci, IncludeComments, IncludeStrings); } if (add) { if (!actualMatches.ContainsKey(currentFileName)) { actualMatches.Add(currentFileName, new List <SearchMatch>()); } actualMatches[currentFileName].Add(match); } matchesChecked++; UserInterfaceManager.ProgressDialog.UpdateProgress((100 * matchesChecked) / totalMatches); } } this.AssociatedDocumentHelper.CloseTemporarilyOpenedDocuments(); return(actualMatches); }
/// <summary> /// Top-level elements lookup /// </summary> /// <param name="token">Element to search</param> /// <param name="result">Response structure</param> public virtual void ResolveTopLevelElement(string token, ASResult result) { // to be implemented // or let empty }
/// <summary> /// A new FindAllReferences refactoring command. /// </summary> /// <param name="target">The target declaration to find references to.</param> /// <param name="output">If true, will send the found results to the trace log and results panel</param> public FindAllReferences(ASResult target, Boolean output) : this(target, output, false) { }
private static void GenerateImplementation(ClassModel iType, ClassModel inClass, ScintillaControl sci, bool detached) { List<string> typesUsed = new List<string>(); StringBuilder sb = new StringBuilder(); string header = TemplateUtils.ReplaceTemplateVariable(TemplateUtils.GetTemplate("ImplementHeader"), "Class", iType.Type); header = TemplateUtils.ReplaceTemplateVariable(header, "BlankLine", detached ? BlankLine : null); sb.Append(header); sb.Append(NewLine); bool entry = true; ASResult result = new ASResult(); IASContext context = ASContext.Context; ContextFeatures features = context.Features; bool canGenerate = false; bool isHaxe = IsHaxe; FlagType flags = (FlagType.Function | FlagType.Getter | FlagType.Setter); if (isHaxe) flags |= FlagType.Variable; iType.ResolveExtends(); // resolve inheritance chain while (!iType.IsVoid() && iType.QualifiedName != "Object") { foreach (MemberModel method in iType.Members) { if ((method.Flags & flags) == 0 || method.Name == iType.Name) continue; // check if method exists ASComplete.FindMember(method.Name, inClass, result, method.Flags, 0); if (!result.IsNull()) continue; string decl; if ((method.Flags & FlagType.Getter) > 0) { if (isHaxe) { decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Property")); string templateName = null; string metadata = null; if (method.Parameters[0].Name == "get") { if (method.Parameters[1].Name == "set") { templateName = "GetterSetter"; metadata = "@:isVar"; } else templateName = "Getter"; } else if (method.Parameters[1].Name == "set") { templateName = "Setter"; } decl = TemplateUtils.ReplaceTemplateVariable(decl, "MetaData", metadata); if (templateName != null) { var accessor = NewLine + TemplateUtils.ToDeclarationString(method, TemplateUtils.GetTemplate(templateName)); accessor = TemplateUtils.ReplaceTemplateVariable(accessor, "Modifiers", null); accessor = TemplateUtils.ReplaceTemplateVariable(accessor, "Member", method.Name); decl += accessor; } } else decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Getter")); } else if ((method.Flags & FlagType.Setter) > 0) decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Setter")); else if ((method.Flags & FlagType.Function) > 0) decl = TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Function")); else decl = NewLine + TemplateUtils.ToDeclarationWithModifiersString(method, TemplateUtils.GetTemplate("Variable")); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Member", "_" + method.Name); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Void", features.voidKey); decl = TemplateUtils.ReplaceTemplateVariable(decl, "Body", null); decl = TemplateUtils.ReplaceTemplateVariable(decl, "BlankLine", NewLine); if (!entry) { decl = TemplateUtils.ReplaceTemplateVariable(decl, "EntryPoint", null); } decl += NewLine; entry = false; sb.Append(decl); canGenerate = true; AddTypeOnce(typesUsed, GetQualifiedType(method.Type, iType)); if (method.Parameters != null && method.Parameters.Count > 0) foreach (MemberModel param in method.Parameters) AddTypeOnce(typesUsed, GetQualifiedType(param.Type, iType)); } // interface inheritance iType = iType.Extends; } if (!canGenerate) return; sci.BeginUndoAction(); try { int position = sci.CurrentPos; if (ASContext.Context.Settings.GenerateImports && typesUsed.Count > 0) { int offset = AddImportsByName(typesUsed, sci.LineFromPosition(position)); position += offset; sci.SetSel(position, position); } InsertCode(position, sb.ToString(), sci); } finally { sci.EndUndoAction(); } }
/// <summary> /// /// </summary> /// <param name="target">The target declaration to find references to.</param> /// <param name="output">If true, will send the found results to the trace log and results panel</param> public FindAllReferences(ASResult target, Boolean output, Boolean ignoreDeclarations) { this.currentTarget = target; this.outputResults = output; this.ignoreDeclarationSource = ignoreDeclarations; }
private static void GenerateVariableJob(GeneratorJobType job, ScintillaNet.ScintillaControl Sci, MemberModel member, bool detach, ClassModel inClass) { int position = 0; MemberModel latest = null; bool isOtherClass = false; Visibility varVisi = job.Equals(GeneratorJobType.Variable) ? GetDefaultVisibility() : Visibility.Public; FlagType ft = job.Equals(GeneratorJobType.Constant) ? FlagType.Constant : FlagType.Variable; // evaluate, if the variable (or constant) should be generated in other class ASResult varResult = ASComplete.GetExpressionType(Sci, Sci.WordEndPosition(Sci.CurrentPos, true)); int contextOwnerPos = GetContextOwnerEndPos(Sci, Sci.WordStartPosition(Sci.CurrentPos, true)); MemberModel isStatic = new MemberModel(); if (contextOwnerPos != -1) { ASResult contextOwnerResult = ASComplete.GetExpressionType(Sci, contextOwnerPos); if (contextOwnerResult != null) { if (contextOwnerResult.Member == null && contextOwnerResult.Type != null) { isStatic.Flags |= FlagType.Static; } } } else if (member != null && (member.Flags & FlagType.Static) > 0) { isStatic.Flags |= FlagType.Static; } ASResult returnType = null; int lineNum = Sci.CurrentLine; string line = Sci.GetLine(lineNum); Match m = Regex.Match(line, "\\b" + Regex.Escape(contextToken) + "\\("); if (m.Success) { returnType = new ASResult(); returnType.Type = ASContext.Context.ResolveType("Function", null); } else { m = Regex.Match(line, @"=\s*[^;\n\r}}]+"); if (m.Success) { int posLineStart = Sci.PositionFromLine(lineNum); if (posLineStart + m.Index >= Sci.CurrentPos) { line = line.Substring(m.Index); StatementReturnType rType = GetStatementReturnType(Sci, inClass, line, posLineStart + m.Index); if (rType != null) { returnType = rType.resolve; } } } } if (varResult.RelClass != null && !varResult.RelClass.IsVoid() && !varResult.RelClass.Equals(inClass)) { AddLookupPosition(); lookupPosition = -1; ASContext.MainForm.OpenEditableDocument(varResult.RelClass.InFile.FileName, false); Sci = ASContext.CurSciControl; isOtherClass = true; FileModel fileModel = new FileModel(); fileModel.Context = ASContext.Context; ASFileParser parser = new ASFileParser(); parser.ParseSrc(fileModel, Sci.Text); foreach (ClassModel cm in fileModel.Classes) { if (cm.QualifiedName.Equals(varResult.RelClass.QualifiedName)) { varResult.RelClass = cm; break; } } inClass = varResult.RelClass; ASContext.Context.UpdateContext(inClass.LineFrom); } latest = GetLatestMemberForVariable(job, inClass, varVisi, isStatic); // if we generate variable in current class.. if (!isOtherClass && member == null) { detach = false; lookupPosition = -1; position = Sci.WordStartPosition(Sci.CurrentPos, true); Sci.SetSel(position, Sci.WordEndPosition(position, true)); } else // if we generate variable in another class { if (latest != null) { position = FindNewVarPosition(Sci, inClass, latest); } else { position = GetBodyStart(inClass.LineFrom, inClass.LineTo, Sci); detach = false; } if (position <= 0) return; Sci.SetSel(position, position); } // if this is a constant, we assign a value to constant string returnTypeStr = null; string eventValue = null; if (job == GeneratorJobType.Constant && returnType == null) { isStatic.Flags |= FlagType.Static; eventValue = "String = \"" + Camelize(contextToken) + "\""; } else if (returnType != null) { ClassModel inClassForImport = null; if (returnType.InClass != null) { inClassForImport = returnType.InClass; } else if (returnType.RelClass != null) { inClassForImport = returnType.RelClass; } else { inClassForImport = inClass; } List<String> imports = new List<string>(); if (returnType.Member != null) { if (returnType.Member.Type != ASContext.Context.Features.voidKey) { returnTypeStr = FormatType(GetShortType(returnType.Member.Type)); imports.Add(getQualifiedType(returnType.Member.Type, inClassForImport)); } } else if (returnType != null && returnType.Type != null) { returnTypeStr = FormatType(GetShortType(returnType.Type.QualifiedName)); imports.Add(getQualifiedType(returnType.Type.QualifiedName, inClassForImport)); } if (imports.Count > 0) { position += AddImportsByName(imports, Sci.LineFromPosition(position)); Sci.SetSel(position, position); } } MemberModel newMember = NewMember(contextToken, isStatic, ft, varVisi); if (returnTypeStr != null) { newMember.Type = returnTypeStr; } else if (eventValue != null) { newMember.Type = eventValue; } GenerateVariable(newMember, position, detach); }
/// <summary> /// Checks if the given match actually is the declaration. /// </summary> static public bool IsMatchTheTarget(ScintillaNet.ScintillaControl Sci, SearchMatch match, ASResult target) { if (Sci == null || target == null || target.inFile == null || target.Member == null) { return(false); } String originalFile = Sci.FileName; // get type at match position ASResult declaration = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); return((declaration.inFile != null && originalFile == declaration.inFile.FileName) && (Sci.CurrentPos == (Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)))); }
private static StatementReturnType GetStatementReturnType(ScintillaNet.ScintillaControl Sci, ClassModel inClass, string line, int startPos) { Regex target = new Regex(@"[;\s\n\r]*", RegexOptions.RightToLeft); Match m = target.Match(line); if (!m.Success) { return null; } line = line.Substring(0, m.Index); if (line.Length == 0) { return null; } line = ReplaceAllStringContents(line); ASResult resolve = null; int pos = -1; string word = null; int stylemask = (1 << Sci.StyleBits) - 1; ClassModel type = null; if (line[line.Length - 1] == ')') { pos = -1; int lastIndex = 0; int bracesBalance = 0; while (true) { int pos1 = line.IndexOf("(", lastIndex); int pos2 = line.IndexOf(")", lastIndex); if (pos1 != -1 && pos2 != -1) { lastIndex = Math.Min(pos1, pos2); } else if (pos1 != -1 || pos2 != -1) { lastIndex = Math.Max(pos1, pos2); } else { break; } if (lastIndex == pos1) { bracesBalance++; if (bracesBalance == 1) { pos = lastIndex; } } else if (lastIndex == pos2) { bracesBalance--; } lastIndex++; } } else { pos = line.Length; } if (pos != -1) { line = line.Substring(0, pos); pos += startPos; pos -= line.Length - line.TrimEnd().Length + 1; pos = Sci.WordEndPosition(pos, true); resolve = ASComplete.GetExpressionType(Sci, pos); if (resolve.IsNull()) resolve = null; word = Sci.GetWordFromPosition(pos); } IASContext ctx = inClass.InFile.Context; m = Regex.Match(line, "new\\s+([\\w\\d.<>,_$-]+)+(<[^]]+>)|(<[^]]+>)", RegexOptions.IgnoreCase); if (m.Success) { string m1 = m.Groups[1].Value; string m2 = m.Groups[2].Value; string cname; if (string.IsNullOrEmpty(m1) && string.IsNullOrEmpty(m2)) cname = m.Groups[0].Value; else cname = String.Concat(m1, m2); if (cname.StartsWith("<")) cname = "Vector." + cname; // literal vector type = ctx.ResolveType(cname, inClass.InFile); if (!type.IsVoid()) resolve = null; } else { char c = (char)Sci.CharAt(pos); if (c == '"' || c == '\'') { type = ctx.ResolveType("String", inClass.InFile); } else if (c == '}') { type = ctx.ResolveType(ctx.Features.objectKey, inClass.InFile); } else if (c == '>') { type = ctx.ResolveType("XML", inClass.InFile); } else if (c == ']') { resolve = ASComplete.GetExpressionType(Sci, pos + 1); if (resolve.Type != null) type = resolve.Type; else type = ctx.ResolveType(ctx.Features.arrayKey, inClass.InFile); resolve = null; } else if (word != null && Char.IsDigit(word[0])) { type = ctx.ResolveType(ctx.Features.numberKey, inClass.InFile); } else if (word == "true" || word == "false") { type = ctx.ResolveType(ctx.Features.booleanKey, inClass.InFile); } if (type != null && type.IsVoid()) type = null; } if (resolve == null) resolve = new ASResult(); if (resolve.Type == null) resolve.Type = type; return new StatementReturnType(resolve, pos, word); }
/// <summary> /// Checks if a given search match actually points to the given target source /// </summary /// <returns>True if the SearchMatch does point to the target source.</returns> static public bool DoesMatchPointToTarget(ScintillaNet.ScintillaControl Sci, SearchMatch match, ASResult target, DocumentHelper associatedDocumentHelper) { if (Sci == null || target == null || target.inFile == null || target.Member == null) { return(false); } // get type at match position ASResult result = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); if (associatedDocumentHelper != null) { // because the declaration lookup opens a document, we should register it with the document helper to be closed later associatedDocumentHelper.RegisterLoadedDocument(PluginBase.MainForm.CurrentDocument); } // check if the result matches the target // TODO: this method of checking their equality seems pretty crude -- is there a better way? if (result == null || result.inFile == null || result.Member == null) { return(false); } Boolean doesMatch = result.inFile.BasePath == target.inFile.BasePath && result.inFile.FileName == target.inFile.FileName && result.Member.LineFrom == target.Member.LineFrom && result.Member.Name == target.Member.Name; return(doesMatch); }
public FunctionParameter(string parameter, string paramType, string paramQualType, ASResult result) { this.paramName = parameter; this.paramType = paramType; this.paramQualType = paramQualType; this.result = result; }
/// <summary> /// Finds the given target in all project files. /// If the target is a local variable or function parameter, it will only search the associated file. /// Note: if running asynchronously, you must supply a listener to "findFinishedHandler" to retrieve the results. /// If running synchronously, do not set listeners and instead use the return value. /// </summary> /// <param name="target">the source member to find references to</param> /// <param name="progressReportHandler">event to fire as search results are compiled</param> /// <param name="findFinishedHandler">event to fire once searching is finished</param> /// <param name="asynchronous">executes in asynchronous mode</param> /// <returns>If "asynchronous" is false, will return the search results, otherwise returns null on bad input or if running in asynchronous mode.</returns> public static FRResults FindTargetInFiles(ASResult target, FRProgressReportHandler progressReportHandler, FRFinishedHandler findFinishedHandler, Boolean asynchronous) { Boolean currentFileOnly = false; // checks target is a member if (target == null || ((target.Member == null || target.Member.Name == null || target.Member.Name == String.Empty) && (target.Type == null || CheckFlag(FlagType.Class, target.Type.Flags)))) { return(null); } else { // if the target we are trying to rename exists as a local variable or a function parameter we only need to search the current file if (target.Member != null && ( target.Member.Access == Visibility.Private || RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.LocalVar) || RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.ParameterVar)) ) { currentFileOnly = true; } } FRConfiguration config; IProject project = PluginBase.CurrentProject; String file = PluginBase.MainForm.CurrentDocument.FileName; // This is out of the project, just look for this file... if (currentFileOnly || !IsProjectRelatedFile(project, file)) { String mask = Path.GetFileName(file); String path = Path.GetDirectoryName(file); config = new FRConfiguration(path, mask, false, GetFRSearch(target.Member.Name)); if (mask.Contains("[model]")) { if (findFinishedHandler != null) { findFinishedHandler(new FRResults()); } return(null); } } else { config = new FRConfiguration(GetAllProjectRelatedFiles(project), GetFRSearch(target.Member.Name)); } config.CacheDocuments = true; FRRunner runner = new FRRunner(); if (progressReportHandler != null) { runner.ProgressReport += progressReportHandler; } if (findFinishedHandler != null) { runner.Finished += findFinishedHandler; } if (asynchronous) { runner.SearchAsync(config); } else { return(runner.SearchSync(config)); } return(null); }
static public void ContextualGenerator(ScintillaNet.ScintillaControl Sci) { if (ASContext.Context is ASContext) (ASContext.Context as ASContext).UpdateCurrentFile(false); // update model if ((ASContext.Context.CurrentClass.Flags & (FlagType.Enum | FlagType.TypeDef)) > 0) return; lookupPosition = -1; int position = Sci.CurrentPos; if (Sci.BaseStyleAt(position) == 19) // on keyword return; bool isNotInterface = (ASContext.Context.CurrentClass.Flags & FlagType.Interface) == 0; int line = Sci.LineFromPosition(position); contextToken = Sci.GetWordFromPosition(position); contextMatch = null; FoundDeclaration found = GetDeclarationAtLine(Sci, line); string text = Sci.GetLine(line); bool suggestItemDeclaration = false; if (isNotInterface && !String.IsNullOrEmpty(contextToken) && Char.IsDigit(contextToken[0])) { ShowConvertToConst(found); return; } ASResult resolve = ASComplete.GetExpressionType(Sci, Sci.WordEndPosition(position, true)); contextResolved = resolve; // ignore automatic vars (MovieClip members) if (isNotInterface && resolve.Member != null && (((resolve.Member.Flags & FlagType.AutomaticVar) > 0) || (resolve.InClass != null && resolve.InClass.QualifiedName == "Object"))) { resolve.Member = null; resolve.Type = null; } if (isNotInterface && found.inClass != ClassModel.VoidClass && contextToken != null) { if (resolve.Member == null && resolve.Type != null && (resolve.Type.Flags & FlagType.Interface) > 0) // implement interface { contextParam = resolve.Type.Type; ShowImplementInterface(found); return; } if (resolve.Member != null && !ASContext.Context.CurrentClass.IsVoid() && (resolve.Member.Flags & FlagType.LocalVar) > 0) // promote to class var { contextMember = resolve.Member; ShowPromoteLocalAndAddParameter(found); return; } } if (contextToken != null && resolve.Member == null) // import declaration { if ((resolve.Type == null || resolve.Type.IsVoid() || !ASContext.Context.IsImported(resolve.Type, line)) && CheckAutoImport(found)) return; if (resolve.Type == null) { int stylemask = (1 << Sci.StyleBits) - 1; suggestItemDeclaration = ASComplete.IsTextStyle(Sci.StyleAt(position - 1) & stylemask); } } if (isNotInterface && found.member != null) { // private var -> property if ((found.member.Flags & FlagType.Variable) > 0 && (found.member.Flags & FlagType.LocalVar) == 0) { // maybe we just want to import the member's non-imported type Match m = Regex.Match(text, String.Format(patternVarDecl, found.member.Name, contextToken)); if (m.Success) { contextMatch = m; ClassModel type = ASContext.Context.ResolveType(contextToken, ASContext.Context.CurrentModel); if (type.IsVoid() && CheckAutoImport(found)) return; } ShowGetSetList(found); return; } // inside a function else if ((found.member.Flags & (FlagType.Function | FlagType.Getter | FlagType.Setter)) > 0 && resolve.Member == null && resolve.Type == null) { if (contextToken != null) { // "generate event handlers" suggestion string re = String.Format(patternEvent, contextToken); Match m = Regex.Match(text, re, RegexOptions.IgnoreCase); if (m.Success) { contextMatch = m; contextParam = CheckEventType(m.Groups["event"].Value); ShowEventList(found); return; } m = Regex.Match(text, String.Format(patternAS2Delegate, contextToken), RegexOptions.IgnoreCase); if (m.Success) { contextMatch = m; ShowDelegateList(found); return; } // suggest delegate if (ASContext.Context.Features.hasDelegates) { m = Regex.Match(text, @"([a-z0-9_.]+)\s*\+=\s*" + contextToken, RegexOptions.IgnoreCase); if (m.Success) { int offset = Sci.PositionFromLine(Sci.LineFromPosition(position)) + m.Groups[1].Index + m.Groups[1].Length; resolve = ASComplete.GetExpressionType(Sci, offset); if (resolve.Member != null) contextMember = ResolveDelegate(resolve.Member.Type, resolve.InFile); contextMatch = m; ShowDelegateList(found); return; } } } else { // insert a default handler name, then "generate event handlers" suggestion Match m = Regex.Match(text, String.Format(patternEvent, ""), RegexOptions.IgnoreCase); if (m.Success) { int regexIndex = m.Index + Sci.PositionFromLine(Sci.CurrentLine); GenerateDefaultHandlerName(Sci, position, regexIndex, m.Groups["event"].Value, true); resolve = ASComplete.GetExpressionType(Sci, Sci.CurrentPos); if (resolve.Member == null || (resolve.Member.Flags & FlagType.AutomaticVar) > 0) { contextMatch = m; contextParam = CheckEventType(m.Groups["event"].Value); ShowEventList(found); } return; } // insert default delegate name, then "generate delegate" suggestion if (ASContext.Context.Features.hasDelegates) { m = Regex.Match(text, @"([a-z0-9_.]+)\s*\+=\s*", RegexOptions.IgnoreCase); if (m.Success) { int offset = Sci.PositionFromLine(Sci.LineFromPosition(position)) + m.Groups[1].Index + m.Groups[1].Length; resolve = ASComplete.GetExpressionType(Sci, offset); if (resolve.Member != null) { contextMember = ResolveDelegate(resolve.Member.Type, resolve.InFile); string delegateName = resolve.Member.Name; if (delegateName.StartsWith("on")) delegateName = delegateName.Substring(2); GenerateDefaultHandlerName(Sci, position, offset, delegateName, false); resolve = ASComplete.GetExpressionType(Sci, Sci.CurrentPos); if (resolve.Member == null || (resolve.Member.Flags & FlagType.AutomaticVar) > 0) { contextMatch = m; ShowDelegateList(found); } return; } } } } } // "Generate fields from parameters" suggestion if (found.member != null && (found.member.Flags & FlagType.Function) > 0 && found.member.Parameters != null && (found.member.Parameters.Count > 0) && resolve.Member != null && (resolve.Member.Flags & FlagType.ParameterVar) > 0) { contextMember = resolve.Member; ShowFieldFromParameter(found); return; } // "add to interface" suggestion if (resolve.Member != null && resolve.Member.Name == found.member.Name && line == found.member.LineFrom && ((found.member.Flags & FlagType.Function) > 0 || (found.member.Flags & FlagType.Getter) > 0 || (found.member.Flags & FlagType.Setter) > 0) && found.inClass != ClassModel.VoidClass && found.inClass.Implements != null && found.inClass.Implements.Count > 0) { string funcName = found.member.Name; FlagType flags = found.member.Flags & ~FlagType.Access; List<string> interfaces = new List<string>(); foreach (string interf in found.inClass.Implements) { bool skip = false; ClassModel cm = ASContext.Context.ResolveType(interf, ASContext.Context.CurrentModel); foreach (MemberModel m in cm.Members) { if (m.Name.Equals(funcName) && m.Flags.Equals(flags)) { skip = true; break; } } if (!skip) { interfaces.Add(interf); } } if (interfaces.Count > 0) { ShowAddInterfaceDefList(found, interfaces); return; } } // "assign var to statement" suggestion int curLine = Sci.CurrentLine; string ln = Sci.GetLine(curLine).TrimEnd(); if (ln.Length > 0 && ln.IndexOf("=") == -1 && ln.Length <= Sci.CurrentPos - Sci.PositionFromLine(curLine)) // cursor at end of line { ShowAssignStatementToVarList(found); return; } } // suggest generate constructor / toString if (isNotInterface && found.member == null && found.inClass != ClassModel.VoidClass && contextToken == null) { bool hasConstructor = false; bool hasToString = false; foreach (MemberModel m in ASContext.Context.CurrentClass.Members) { if (!hasConstructor && (m.Flags & FlagType.Constructor) > 0) hasConstructor = true; if (!hasToString && (m.Flags & FlagType.Function) > 0 && m.Name.Equals("toString")) hasToString = true; } if (!hasConstructor || !hasToString) { ShowConstructorAndToStringList(found, hasConstructor, hasToString); return; } } if (isNotInterface && resolve.Member != null && resolve.Type != null && resolve.Type.QualifiedName == "String" && found.inClass != ClassModel.VoidClass) { int lineStartPos = Sci.PositionFromLine(Sci.CurrentLine); string lineStart = text.Substring(0, Sci.CurrentPos - lineStartPos); Match m = Regex.Match(lineStart, String.Format(@"new\s+(?<event>\w+)\s*\(\s*\w+", lineStart)); if (m.Success) { Group g = m.Groups["event"]; ASResult eventResolve = ASComplete.GetExpressionType(Sci, lineStartPos + g.Index + g.Length); if (eventResolve != null && eventResolve.Type != null) { ClassModel aType = eventResolve.Type; aType.ResolveExtends(); while (!aType.IsVoid() && aType.QualifiedName != "Object") { if (aType.QualifiedName == "flash.events.Event") { contextParam = eventResolve.Type.QualifiedName; ShowEventMetatagList(found); return; } aType = aType.Extends; } } } } // suggest declaration if (contextToken != null) { if (suggestItemDeclaration) { Match m = Regex.Match(text, String.Format(patternClass, contextToken)); if (m.Success) { contextMatch = m; ShowNewClassList(found); } else if (!found.inClass.IsVoid()) { m = Regex.Match(text, String.Format(patternMethod, contextToken)); if (m.Success) { contextMatch = m; ShowNewMethodList(found); } else ShowNewVarList(found); } } else { if (resolve != null && resolve.InClass != null && resolve.InClass.InFile != null && resolve.Member != null && (resolve.Member.Flags & FlagType.Function) > 0 && File.Exists(resolve.InClass.InFile.FileName) && !resolve.InClass.InFile.FileName.StartsWith(PathHelper.AppDir)) { Match m = Regex.Match(text, String.Format(patternMethodDecl, contextToken)); Match m2 = Regex.Match(text, String.Format(patternMethod, contextToken)); if (!m.Success && m2.Success) { contextMatch = m; ShowChangeMethodDeclList(found); } } else if (resolve != null && resolve.Type != null && resolve.Type.InFile != null && resolve.RelClass != null && File.Exists(resolve.Type.InFile.FileName) && !resolve.Type.InFile.FileName.StartsWith(PathHelper.AppDir)) { Match m = Regex.Match(text, String.Format(patternClass, contextToken)); if (m.Success) { contextMatch = m; ShowChangeConstructorDeclList(found); } } } } // TODO: Empty line, show generators list? }
/// <summary> /// Checks if a given search match actually points to the given target source /// </summary /// <returns>True if the SearchMatch does point to the target source.</returns> public static ASResult DeclarationLookupResult(ScintillaNet.ScintillaControl Sci, int position) { if (!ASContext.Context.IsFileValid || (Sci == null)) { return(null); } // get type at cursor position ASResult result = ASComplete.GetExpressionType(Sci, position); // browse to package folder if (result.IsPackage && result.inFile != null) { return(null); } // open source and show declaration if (!result.IsNull()) { if (result.Member != null && (result.Member.Flags & FlagType.AutomaticVar) > 0) { return(null); } FileModel model = result.inFile ?? ((result.Member != null && result.Member.InFile != null) ? result.Member.InFile : null) ?? ((result.Type != null) ? result.Type.InFile : null); if (model == null || model.FileName == "") { return(null); } ClassModel inClass = result.inClass ?? result.Type; // for Back command int lookupLine = Sci.LineFromPosition(Sci.CurrentPos); int lookupCol = Sci.CurrentPos - Sci.PositionFromLine(lookupLine); ASContext.Panel.SetLastLookupPosition(ASContext.Context.CurrentFile, lookupLine, lookupCol); // open the file if (model != ASContext.Context.CurrentModel) { // cached files declarations have no line numbers if (model.CachedModel && model.Context != null) { ASFileParser.ParseFile(model); if (inClass != null && !inClass.IsVoid()) { inClass = model.GetClassByName(inClass.Name); if (result.Member != null) { result.Member = inClass.Members.Search(result.Member.Name, 0, 0); } } else { result.Member = model.Members.Search(result.Member.Name, 0, 0); } } if (model.FileName.Length > 0 && File.Exists(model.FileName)) { ASContext.MainForm.OpenEditableDocument(model.FileName, false); } else { ASComplete.OpenVirtualFile(model); result.inFile = ASContext.Context.CurrentModel; if (result.inFile == null) { return(null); } if (inClass != null) { inClass = result.inFile.GetClassByName(inClass.Name); if (result.Member != null) { result.Member = inClass.Members.Search(result.Member.Name, 0, 0); } } else if (result.Member != null) { result.Member = result.inFile.Members.Search(result.Member.Name, 0, 0); } } } if ((inClass == null || inClass.IsVoid()) && result.Member == null) { return(null); } Sci = ASContext.CurSciControl; if (Sci == null) { return(null); } int line = 0; string name = null; bool isClass = false; // member if (result.Member != null && result.Member.LineFrom > 0) { line = result.Member.LineFrom; name = result.Member.Name; } // class declaration else if (inClass.LineFrom > 0) { line = inClass.LineFrom; name = inClass.Name; isClass = true; // constructor foreach (MemberModel member in inClass.Members) { if ((member.Flags & FlagType.Constructor) > 0) { line = member.LineFrom; name = member.Name; isClass = false; break; } } } if (line > 0) // select { if (isClass) { ASComplete.LocateMember("(class|interface)", name, line); } else { ASComplete.LocateMember("(function|var|const|get|set|property|[,(])", name, line); } } return(result); } return(null); }
/// <summary> /// Checks if a given search match actually points to the given target source /// </summary /// <returns>True if the SearchMatch does point to the target source.</returns> public static bool DoesMatchPointToTarget(ScintillaNet.ScintillaControl Sci, SearchMatch match, ASResult target, DocumentHelper associatedDocumentHelper) { if (Sci == null || target == null) return false; FileModel targetInFile = null; if (target.InFile != null) targetInFile = target.InFile; else if (target.Member != null && target.InClass == null) targetInFile = target.Member.InFile; Boolean matchMember = targetInFile != null && target.Member != null; Boolean matchType = target.Member == null && target.IsStatic && target.Type != null; if (!matchMember && !matchType) return false; ASResult result = null; // get type at match position if (match.Index < Sci.Text.Length) // TODO: find out rare cases of incorrect index reported { result = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); if (associatedDocumentHelper != null) { // because the declaration lookup opens a document, we should register it with the document helper to be closed later associatedDocumentHelper.RegisterLoadedDocument(PluginBase.MainForm.CurrentDocument); } } // check if the result matches the target if (result == null || (result.InFile == null && result.Type == null)) return false; if (matchMember) { if (result.Member == null) return false; var resultInFile = result.InClass != null ? result.InFile : result.Member.InFile; return resultInFile.BasePath == targetInFile.BasePath && resultInFile.FileName == targetInFile.FileName && result.Member.LineFrom == target.Member.LineFrom && result.Member.Name == target.Member.Name; } else // type { if (result.Type == null) return false; if (result.Type.QualifiedName == target.Type.QualifiedName) return true; return false; } }
/// <summary> /// Finds the given target in all project files. /// If the target is a local variable or function parameter, it will only search the associated file. /// Note: if running asynchronously, you must supply a listener to "findFinishedHandler" to retrieve the results. /// If running synchronously, do not set listeners and instead use the return value. /// </summary> /// <param name="target">the source member to find references to</param> /// <param name="progressReportHandler">event to fire as search results are compiled</param> /// <param name="findFinishedHandler">event to fire once searching is finished</param> /// <param name="asynchronous">executes in asynchronous mode</param> /// <returns>If "asynchronous" is false, will return the search results, otherwise returns null on bad input or if running in asynchronous mode.</returns> public static FRResults FindTargetInFiles(ASResult target, FRProgressReportHandler progressReportHandler, FRFinishedHandler findFinishedHandler, Boolean asynchronous) { Boolean currentFileOnly = false; // checks target is a member if (target == null || ((target.Member == null || target.Member.Name == null || target.Member.Name == String.Empty) && (target.Type == null || CheckFlag(FlagType.Class, target.Type.Flags)))) { return null; } else { // if the target we are trying to rename exists as a local variable or a function parameter we only need to search the current file if (target.Member != null && (RefactoringHelpera.CheckFlag(target.Member.Flags, FlagType.LocalVar) || RefactoringHelpera.CheckFlag(target.Member.Flags, FlagType.ParameterVar))) { currentFileOnly = true; } } // sets the FindInFiles settings to the project root, *.as files, and recursive String path = Path.GetDirectoryName(PluginBase.CurrentProject.ProjectPath); if (!PluginBase.MainForm.CurrentDocument.FileName.StartsWith(path)) { // This is out of the project, just look for this file... currentFileOnly = true; } String mask = "*.as;*.hx"; Boolean recursive = true; // but if it's only the current file, let's just search that! if (currentFileOnly) { path = Path.GetDirectoryName(PluginBase.MainForm.CurrentDocument.FileName); mask = Path.GetFileName(PluginBase.MainForm.CurrentDocument.FileName); recursive = false; } FRConfiguration config = new FRConfiguration(path, mask, recursive, GetFRSearch(target.Member.Name)); config.CacheDocuments = true; FRRunner runner = new FRRunner(); if (progressReportHandler != null) { runner.ProgressReport += progressReportHandler; } if (findFinishedHandler != null) { runner.Finished += findFinishedHandler; } if (asynchronous) runner.SearchAsync(config); else return runner.SearchSync(config); return null; }
/// <summary> /// Checks if the given match actually is the declaration. /// </summary> public static bool IsMatchTheTarget(ScintillaNet.ScintillaControl Sci, SearchMatch match, ASResult target) { if (Sci == null || target == null || target.InFile == null || target.Member == null) { return false; } String originalFile = Sci.FileName; // get type at match position ASResult declaration = DeclarationLookupResult(Sci, Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value)); return (declaration.InFile != null && originalFile == declaration.InFile.FileName) && (Sci.CurrentPos == (Sci.MBSafePosition(match.Index) + Sci.MBSafeTextLength(match.Value))); }
public static FRResults FindTargetInCurrentFile(ASResult target, /*FRProgressReportHandler progressReportHandler,*/ FRFinishedHandler findFinishedHandler, Boolean asynchronous) { //Boolean currentFileOnly = false; // checks target is a member if (target == null || ((target.Member == null || target.Member.Name == null || target.Member.Name == String.Empty) && (target.Type == null || CheckFlag(FlagType.Class, target.Type.Flags)))) { return(null); } //else //{ /* * // if the target we are trying to rename exists as a local variable or a function parameter we only need to search the current file * if (target.Member != null && (RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.LocalVar) || RefactoringHelper.CheckFlag(target.Member.Flags, FlagType.ParameterVar))) * { * currentFileOnly = true; * } */ //} // sets the FindInFiles settings to the project root, *.as files, and recursive //String path = Path.GetDirectoryName(PluginBase.CurrentProject.ProjectPath); /* * if (!PluginBase.MainForm.CurrentDocument.FileName.StartsWith(path)) * { * // This is out of the project, just look for this file... * currentFileOnly = true; * } */ //String mask = "*.as;*.hx"; //Boolean recursive = true; // but if it's only the current file, let's just search that! //if (currentFileOnly) //{ //path = Path.GetDirectoryName(PluginBase.MainForm.CurrentDocument.FileName); //mask = Path.GetFileName(PluginBase.MainForm.CurrentDocument.FileName); //recursive = false; //} FRConfiguration config = new FRConfiguration(Path.GetDirectoryName(PluginBase.MainForm.CurrentDocument.FileName), Path.GetFileName(PluginBase.MainForm.CurrentDocument.FileName), false, GetFRSearch(target.Member.Name)); config.CacheDocuments = true; FRRunner runner = new FRRunner(); /* * if (progressReportHandler != null) * { * runner.ProgressReport += progressReportHandler; * } */ if (findFinishedHandler != null) { runner.Finished += findFinishedHandler; } if (asynchronous) { runner.SearchAsync(config); } else { return(runner.SearchSync(config)); } return(null); }