Bug 1515736 - [release 111] Stop using immutable for search results (#7506). r=lsmyth
authorJason Laster <jlaster@mozilla.com>
Fri, 21 Dec 2018 11:49:42 -0500
changeset 451725 e5f127555df6b45147c73c6c46d3a92884fdd459
parent 451724 026689094355e6a24849b4b650c124b39321d043
child 451726 2f3d11e79be8a6c6bbc6fa3e831f9091c1c2323b
push id35252
push userccoroiu@mozilla.com
push dateFri, 21 Dec 2018 21:56:22 +0000
treeherdermozilla-central@b23630094b9c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsmyth
bugs1515736
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1515736 - [release 111] Stop using immutable for search results (#7506). r=lsmyth
devtools/client/debugger/new/src/components/ProjectSearch.js
devtools/client/debugger/new/src/reducers/project-text-search.js
devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js
--- a/devtools/client/debugger/new/src/components/ProjectSearch.js
+++ b/devtools/client/debugger/new/src/components/ProjectSearch.js
@@ -152,30 +152,18 @@ export class ProjectSearch extends Compo
     this.props.doSearchForHighlight(
       this.state.inputValue,
       getEditor(),
       matchItem.line,
       matchItem.column
     );
   };
 
-  getResults = (): Result[] => {
-    const { results } = this.props;
-    return results
-      .toJS()
-      .map(result => ({
-        type: "RESULT",
-        ...result,
-        matches: result.matches.map(m => ({ type: "MATCH", ...m }))
-      }))
-      .filter(result => result.filepath && result.matches.length > 0);
-  };
-
   getResultCount = () =>
-    this.getResults().reduce((count, file) => count + file.matches.length, 0);
+    this.props.results.reduce((count, file) => count + file.matches.length, 0);
 
   onKeyDown = (e: SyntheticKeyboardEvent<HTMLInputElement>) => {
     if (e.key === "Escape") {
       return;
     }
 
     e.stopPropagation();
 
@@ -266,18 +254,17 @@ export class ProjectSearch extends Compo
   ) => {
     if (item.type === "RESULT") {
       return this.renderFile(item, focused, expanded, setExpanded);
     }
     return this.renderMatch(item, focused);
   };
 
   renderResults = () => {
-    const results = this.getResults();
-    const { status } = this.props;
+    const { status, results } = this.props;
     if (!this.props.query) {
       return;
     }
     if (results.length && status === statusType.done) {
       return (
         <ManagedTree
           getRoots={() => results}
           getChildren={file => file.matches || []}
--- a/devtools/client/debugger/new/src/reducers/project-text-search.js
+++ b/devtools/client/debugger/new/src/reducers/project-text-search.js
@@ -5,102 +5,95 @@
 // @flow
 // @format
 
 /**
  * Project text search reducer
  * @module reducers/project-text-search
  */
 
-import * as I from "immutable";
-import makeRecord from "../utils/makeRecord";
-
 import type { Action } from "../actions/types";
-import type { Record } from "../utils/makeRecord";
-import type { List } from "immutable";
 
 export type Search = {
-  id: string,
-  filepath: string,
-  matches: I.List<any>
+  +sourceId: string,
+  +filepath: string,
+  +matches: any[]
 };
 export type StatusType = "INITIAL" | "FETCHING" | "DONE" | "ERROR";
 export const statusType = {
   initial: "INITIAL",
   fetching: "FETCHING",
   done: "DONE",
   error: "ERROR"
 };
 
-export type ResultRecord = Record<Search>;
-export type ResultList = List<ResultRecord>;
+export type ResultList = Search[];
 export type ProjectTextSearchState = {
-  query: string,
-  results: ResultList,
-  status: string
+  +query: string,
+  +results: ResultList,
+  +status: string
 };
 
-export function initialProjectTextSearchState(): Record<
-  ProjectTextSearchState
-> {
-  return makeRecord(
-    ({
-      query: "",
-      results: I.List(),
-      status: statusType.initial
-    }: ProjectTextSearchState)
-  )();
+export function initialProjectTextSearchState(): ProjectTextSearchState {
+  return {
+    query: "",
+    results: [],
+    status: statusType.initial
+  };
 }
 
 function update(
-  state: Record<ProjectTextSearchState> = initialProjectTextSearchState(),
+  state: ProjectTextSearchState = initialProjectTextSearchState(),
   action: Action
-): Record<ProjectTextSearchState> {
+): ProjectTextSearchState {
   switch (action.type) {
     case "ADD_QUERY":
-      const actionCopy = action;
-      return state.update("query", value => actionCopy.query);
+      return { ...state, query: action.query };
 
     case "CLEAR_QUERY":
-      return state.merge({
+      return {
+        ...state,
         query: "",
         status: statusType.initial
-      });
+      };
 
     case "ADD_SEARCH_RESULT":
-      const results = state.get("results");
-      return state.merge({ results: results.push(action.result) });
+      const results = state.results;
+      if (action.result.matches.length === 0) {
+        return state;
+      }
+
+      const result = {
+        type: "RESULT",
+        ...action.result,
+        matches: action.result.matches.map(m => ({ type: "MATCH", ...m }))
+      };
+      return { ...state, results: [...results, result] };
 
     case "UPDATE_STATUS":
-      return state.merge({ status: action.status });
+      return { ...state, status: action.status };
 
     case "CLEAR_SEARCH_RESULTS":
-      return state.merge({
-        results: state.get("results").clear()
-      });
+      return { ...state, results: [] };
 
     case "CLEAR_SEARCH":
     case "CLOSE_PROJECT_SEARCH":
     case "NAVIGATE":
-      return state.merge({
-        query: "",
-        results: state.get("results").clear(),
-        status: statusType.initial
-      });
+      return initialProjectTextSearchState();
   }
   return state;
 }
 
-type OuterState = { projectTextSearch: Record<ProjectTextSearchState> };
+type OuterState = { projectTextSearch: ProjectTextSearchState };
 
 export function getTextSearchResults(state: OuterState) {
-  return state.projectTextSearch.get("results");
+  return state.projectTextSearch.results;
 }
 
 export function getTextSearchStatus(state: OuterState) {
-  return state.projectTextSearch.get("status");
+  return state.projectTextSearch.status;
 }
 
 export function getTextSearchQuery(state: OuterState) {
-  return state.projectTextSearch.get("query");
+  return state.projectTextSearch.query;
 }
 
 export default update;
--- a/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js
+++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-search-project.js
@@ -21,19 +21,17 @@ async function selectResult(dbg) {
   );
   await clickElement(dbg, "fileMatch");
   return select;
 }
 
 function getResultsCount(dbg) {
   const matches = dbg.selectors
     .getTextSearchResults(dbg.getState())
-    .valueSeq()
-    .map(file => file.matches)
-    .toJS();
+    .map(file => file.matches);
 
   return [...matches].length;
 }
 
 // Testing project search
 add_task(async function() {
   await pushPref("devtools.debugger.project-text-search-enabled", true);