зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1539493 - Remove source metadata. r=loganfsmyth
Differential Revision: https://phabricator.services.mozilla.com/D25122 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
4e9ae4c589
Коммит
2dc9aa5a90
|
@ -15,7 +15,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,7 @@
|
|||
"byName": {},
|
||||
"byBlocks": {},
|
||||
"usedIds": {
|
||||
"0": 0
|
||||
"1": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15207,15 +15207,15 @@ var _getFunctionName = __webpack_require__(158);
|
|||
|
||||
var _getFunctionName2 = _interopRequireDefault(_getFunctionName);
|
||||
|
||||
var _frameworks = __webpack_require__(159);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
let symbolDeclarations = new Map();
|
||||
let symbolDeclarations = new Map(); /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
function getUniqueIdentifiers(identifiers) {
|
||||
const newIdentifiers = [];
|
||||
|
@ -15401,7 +15401,8 @@ function extractSymbols(sourceId) {
|
|||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
loading: false
|
||||
loading: false,
|
||||
framework: undefined
|
||||
};
|
||||
|
||||
const state = {
|
||||
|
@ -15424,6 +15425,7 @@ function extractSymbols(sourceId) {
|
|||
// comments are extracted separately from the AST
|
||||
symbols.comments = (0, _helpers.getComments)(ast);
|
||||
symbols.identifiers = getUniqueIdentifiers(symbols.identifiers);
|
||||
symbols.framework = (0, _frameworks.getFramework)(symbols);
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
@ -17464,32 +17466,23 @@ var _types = __webpack_require__(3);
|
|||
|
||||
var t = _interopRequireWildcard(_types);
|
||||
|
||||
var _getSymbols = __webpack_require__(117);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
function getFramework(sourceId) {
|
||||
const sourceSymbols = (0, _getSymbols.getSymbols)(sourceId);
|
||||
|
||||
if (isReactComponent(sourceSymbols)) {
|
||||
function getFramework(symbols) {
|
||||
if (isReactComponent(symbols)) {
|
||||
return "React";
|
||||
}
|
||||
if (isAngularComponent(sourceSymbols)) {
|
||||
if (isAngularComponent(symbols)) {
|
||||
return "Angular";
|
||||
}
|
||||
if (isVueComponent(sourceSymbols)) {
|
||||
if (isVueComponent(symbols)) {
|
||||
return "Vue";
|
||||
}
|
||||
}
|
||||
} /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// React
|
||||
|
||||
function isReactComponent(sourceSymbols) {
|
||||
const { imports, classes, callExpressions } = sourceSymbols;
|
||||
function isReactComponent({ imports, classes, callExpressions }) {
|
||||
return importsReact(imports) || requiresReact(callExpressions) || extendsReactComponent(classes);
|
||||
}
|
||||
|
||||
|
@ -17505,19 +17498,13 @@ function extendsReactComponent(classes) {
|
|||
return classes.some(classObj => t.isIdentifier(classObj.parent, { name: "Component" }) || t.isIdentifier(classObj.parent, { name: "PureComponent" }) || t.isMemberExpression(classObj.parent, { computed: false }) && t.isIdentifier(classObj.parent, { name: "Component" }));
|
||||
}
|
||||
|
||||
// Angular
|
||||
|
||||
const isAngularComponent = sourceSymbols => {
|
||||
const { memberExpressions } = sourceSymbols;
|
||||
function isAngularComponent({ memberExpressions }) {
|
||||
return memberExpressions.some(item => item.expression == "angular.controller" || item.expression == "angular.module");
|
||||
};
|
||||
}
|
||||
|
||||
// Vue
|
||||
|
||||
const isVueComponent = sourceSymbols => {
|
||||
const { identifiers } = sourceSymbols;
|
||||
function isVueComponent({ identifiers }) {
|
||||
return identifiers.some(identifier => identifier.name == "Vue");
|
||||
};
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
/* 160 */
|
||||
|
|
|
@ -4,18 +4,7 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import {
|
||||
getSource,
|
||||
getSourceFromId,
|
||||
getSourceThreads,
|
||||
getSymbols,
|
||||
getSelectedLocation
|
||||
} from "../selectors";
|
||||
|
||||
import { mapFrames } from "./pause";
|
||||
import { updateTab } from "./tabs";
|
||||
|
||||
import { PROMISE } from "./utils/middleware/promise";
|
||||
import { getSourceFromId, getSelectedLocation } from "../selectors";
|
||||
|
||||
import { setInScopeLines } from "./ast/setInScopeLines";
|
||||
|
||||
|
@ -23,54 +12,8 @@ import * as parser from "../workers/parser";
|
|||
|
||||
import { isLoaded } from "../utils/source";
|
||||
|
||||
import type { SourceId } from "../types";
|
||||
import type { ThunkArgs, Action } from "./types";
|
||||
|
||||
export function setSourceMetaData(sourceId: SourceId) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const source = getSource(getState(), sourceId);
|
||||
if (!source || !isLoaded(source) || source.isWasm) {
|
||||
return;
|
||||
}
|
||||
|
||||
const framework = await parser.getFramework(source.id);
|
||||
if (framework) {
|
||||
dispatch(updateTab(source, framework));
|
||||
}
|
||||
|
||||
dispatch(
|
||||
({
|
||||
type: "SET_SOURCE_METADATA",
|
||||
sourceId: source.id,
|
||||
sourceMetaData: {
|
||||
framework
|
||||
}
|
||||
}: Action)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function setSymbols(sourceId: SourceId) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
const source = getSourceFromId(getState(), sourceId);
|
||||
|
||||
if (source.isWasm || getSymbols(getState(), source) || !isLoaded(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await dispatch({
|
||||
type: "SET_SYMBOLS",
|
||||
sourceId,
|
||||
[PROMISE]: parser.getSymbols(sourceId)
|
||||
});
|
||||
|
||||
const threads = getSourceThreads(getState(), source);
|
||||
await Promise.all(threads.map(thread => dispatch(mapFrames(thread))));
|
||||
|
||||
await dispatch(setSourceMetaData(sourceId));
|
||||
};
|
||||
}
|
||||
|
||||
export function setOutOfScopeLocations() {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const location = getSelectedLocation(getState());
|
||||
|
|
|
@ -8,3 +8,4 @@ export * from "./loadSourceText";
|
|||
export * from "./newSources";
|
||||
export * from "./prettyPrint";
|
||||
export * from "./select";
|
||||
export { setSymbols } from "./symbols";
|
||||
|
|
|
@ -14,4 +14,5 @@ CompiledModules(
|
|||
'newSources.js',
|
||||
'prettyPrint.js',
|
||||
'select.js',
|
||||
'symbols.js'
|
||||
)
|
||||
|
|
|
@ -8,7 +8,7 @@ import assert from "../../utils/assert";
|
|||
import { recordEvent } from "../../utils/telemetry";
|
||||
import { remapBreakpoints } from "../breakpoints";
|
||||
|
||||
import { setSymbols } from "../ast";
|
||||
import { setSymbols } from "./symbols";
|
||||
import { prettyPrint } from "../../workers/pretty-print";
|
||||
import { getPrettySourceURL, isLoaded } from "../../utils/source";
|
||||
import { loadSourceText } from "./loadSourceText";
|
||||
|
|
|
@ -13,7 +13,8 @@ import { isOriginalId } from "devtools-source-map";
|
|||
|
||||
import { getSourceFromId } from "../../reducers/sources";
|
||||
import { getSourcesForTabs } from "../../reducers/tabs";
|
||||
import { setOutOfScopeLocations, setSymbols } from "../ast";
|
||||
import { setOutOfScopeLocations } from "../ast";
|
||||
import { setSymbols } from "./symbols";
|
||||
import { closeActiveSearch, updateActiveFileSearch } from "../ui";
|
||||
|
||||
import { togglePrettyPrint } from "./prettyPrint";
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
import { getSourceFromId, getSourceThreads, getSymbols } from "../../selectors";
|
||||
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import { mapFrames } from "../pause";
|
||||
import { updateTab } from "../tabs";
|
||||
|
||||
import * as parser from "../../workers/parser";
|
||||
|
||||
import { isLoaded } from "../../utils/source";
|
||||
|
||||
import type { SourceId } from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
export function setSymbols(sourceId: SourceId) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
const source = getSourceFromId(getState(), sourceId);
|
||||
|
||||
if (source.isWasm || getSymbols(getState(), source) || !isLoaded(source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await dispatch({
|
||||
type: "SET_SYMBOLS",
|
||||
sourceId,
|
||||
[PROMISE]: parser.getSymbols(sourceId)
|
||||
});
|
||||
|
||||
const threads = getSourceThreads(getState(), source);
|
||||
await Promise.all(threads.map(thread => dispatch(mapFrames(thread))));
|
||||
|
||||
const symbols = getSymbols(getState(), source);
|
||||
if (symbols.framework) {
|
||||
dispatch(updateTab(source, symbols.framework));
|
||||
}
|
||||
};
|
||||
}
|
|
@ -19,7 +19,6 @@ const {
|
|||
getSourceCount,
|
||||
getSelectedSource,
|
||||
getSourceTabs,
|
||||
getSourceMetaData,
|
||||
getOutOfScopeLocations,
|
||||
getSelectedLocation
|
||||
} = selectors;
|
||||
|
@ -67,11 +66,7 @@ describe("sources", () => {
|
|||
}
|
||||
expect(source.id).toEqual("foo1");
|
||||
|
||||
await waitForState(
|
||||
store,
|
||||
state =>
|
||||
getOutOfScopeLocations(state) && getSourceMetaData(state, source.id)
|
||||
);
|
||||
await waitForState(store, state => getOutOfScopeLocations(state));
|
||||
const locations = getOutOfScopeLocations(getState());
|
||||
expect(locations).toHaveLength(1);
|
||||
});
|
||||
|
|
|
@ -20,9 +20,9 @@ const {
|
|||
getSource,
|
||||
getSymbols,
|
||||
getOutOfScopeLocations,
|
||||
getSourceMetaData,
|
||||
getInScopeLines,
|
||||
isSymbolsLoading
|
||||
isSymbolsLoading,
|
||||
getFramework
|
||||
} = selectors;
|
||||
|
||||
import { prefs } from "../../utils/prefs";
|
||||
|
@ -63,41 +63,6 @@ const evaluationResult = {
|
|||
};
|
||||
|
||||
describe("ast", () => {
|
||||
describe("setSourceMetaData", () => {
|
||||
it("should detect react components", async () => {
|
||||
const store = createStore(threadClient, {}, sourceMaps);
|
||||
const { dispatch, getState } = store;
|
||||
const source = makeOriginalSource("reactComponent.js");
|
||||
|
||||
await dispatch(actions.newSource(makeSource("reactComponent.js")));
|
||||
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(actions.loadSourceText(getSource(getState(), source.id)));
|
||||
await dispatch(actions.setSourceMetaData(source.id));
|
||||
|
||||
await waitForState(store, state => {
|
||||
const metaData = getSourceMetaData(state, source.id);
|
||||
return metaData && metaData.framework;
|
||||
});
|
||||
|
||||
const sourceMetaData = getSourceMetaData(getState(), source.id);
|
||||
expect(sourceMetaData.framework).toBe("React");
|
||||
});
|
||||
|
||||
it("should not give false positive on non react components", async () => {
|
||||
const store = createStore(threadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const base = makeSource("base.js");
|
||||
await dispatch(actions.newSource(base));
|
||||
await dispatch(actions.loadSourceText(base));
|
||||
await dispatch(actions.setSourceMetaData("base.js"));
|
||||
|
||||
const sourceMetaData = getSourceMetaData(getState(), base.id);
|
||||
expect(sourceMetaData.framework).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setSymbols", () => {
|
||||
describe("when the source is loaded", () => {
|
||||
it("should be able to set symbols", async () => {
|
||||
|
@ -132,6 +97,36 @@ describe("ast", () => {
|
|||
expect(baseSymbols).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("frameworks", () => {
|
||||
it("should detect react components", async () => {
|
||||
const store = createStore(threadClient, {}, sourceMaps);
|
||||
const { dispatch, getState } = store;
|
||||
const source = makeOriginalSource("reactComponent.js");
|
||||
|
||||
await dispatch(actions.newSource(makeSource("reactComponent.js")));
|
||||
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(
|
||||
actions.loadSourceText(getSource(getState(), source.id))
|
||||
);
|
||||
await dispatch(actions.setSymbols(source.id));
|
||||
|
||||
expect(getFramework(getState(), source)).toBe("React");
|
||||
});
|
||||
|
||||
it("should not give false positive on non react components", async () => {
|
||||
const store = createStore(threadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const base = makeSource("base.js");
|
||||
await dispatch(actions.newSource(base));
|
||||
await dispatch(actions.loadSourceText(base));
|
||||
await dispatch(actions.setSymbols("base.js"));
|
||||
|
||||
expect(getFramework(getState(), base)).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("getOutOfScopeLocations", () => {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
// @flow
|
||||
|
||||
import type { SymbolDeclarations, AstLocation } from "../../workers/parser";
|
||||
import type { SourceMetaDataType } from "../../reducers/types";
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
|
||||
export type ASTAction =
|
||||
|
@ -36,11 +35,6 @@ export type ASTAction =
|
|||
cursorPos: any
|
||||
}
|
||||
>
|
||||
| {|
|
||||
+type: "SET_SOURCE_METADATA",
|
||||
+sourceId: string,
|
||||
+sourceMetaData: SourceMetaDataType
|
||||
|}
|
||||
| {|
|
||||
+type: "CLEAR_SELECTION"
|
||||
|};
|
||||
|
|
|
@ -12,17 +12,17 @@ import AccessibleImage from "./AccessibleImage";
|
|||
|
||||
import { getSourceClassnames } from "../../utils/source";
|
||||
import { getFramework } from "../../utils/tabs";
|
||||
import { getSourceMetaData, getTabs } from "../../selectors";
|
||||
import { getSymbols, getTabs } from "../../selectors";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { SourceMetaDataType } from "../../reducers/ast";
|
||||
import type { Symbols } from "../../reducers/types";
|
||||
|
||||
import "./SourceIcon.css";
|
||||
|
||||
type Props = {
|
||||
source: Source,
|
||||
// sourceMetaData will provide framework information
|
||||
sourceMetaData: SourceMetaDataType,
|
||||
// symbols will provide framework information
|
||||
symbols: Symbols,
|
||||
// An additional validator for the icon returned
|
||||
shouldHide?: Function,
|
||||
framework?: string
|
||||
|
@ -30,10 +30,10 @@ type Props = {
|
|||
|
||||
class SourceIcon extends PureComponent<Props> {
|
||||
render() {
|
||||
const { shouldHide, source, sourceMetaData, framework } = this.props;
|
||||
const { shouldHide, source, symbols, framework } = this.props;
|
||||
const iconClass = framework
|
||||
? framework.toLowerCase()
|
||||
: getSourceClassnames(source, sourceMetaData);
|
||||
: getSourceClassnames(source, symbols);
|
||||
|
||||
if (shouldHide && shouldHide(iconClass)) {
|
||||
return null;
|
||||
|
@ -45,7 +45,7 @@ class SourceIcon extends PureComponent<Props> {
|
|||
|
||||
export default connect((state, props) => {
|
||||
return {
|
||||
sourceMetaData: getSourceMetaData(state, props.source.id),
|
||||
symbols: getSymbols(state, props.source),
|
||||
framework: getFramework(getTabs(state), props.source.url)
|
||||
};
|
||||
})(SourceIcon);
|
||||
|
|
|
@ -43,8 +43,7 @@ export type ASTState = {
|
|||
+emptyLines: EmptyLinesMap,
|
||||
+outOfScopeLocations: ?Array<AstLocation>,
|
||||
+inScopeLines: ?Array<number>,
|
||||
+preview: Preview,
|
||||
+sourceMetaData: SourceMetaDataMap
|
||||
+preview: Preview
|
||||
};
|
||||
|
||||
export function initialASTState(): ASTState {
|
||||
|
@ -53,8 +52,7 @@ export function initialASTState(): ASTState {
|
|||
emptyLines: {},
|
||||
outOfScopeLocations: null,
|
||||
inScopeLines: null,
|
||||
preview: null,
|
||||
sourceMetaData: {}
|
||||
preview: null
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -113,14 +111,6 @@ function update(state: ASTState = initialASTState(), action: Action): ASTState {
|
|||
return initialASTState();
|
||||
}
|
||||
|
||||
case "SET_SOURCE_METADATA": {
|
||||
const { sourceId, sourceMetaData } = action;
|
||||
return {
|
||||
...state,
|
||||
sourceMetaData: { ...state.sourceMetaData, [sourceId]: sourceMetaData }
|
||||
};
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
|
@ -149,6 +139,13 @@ export function hasSymbols(state: OuterState, source: Source): boolean {
|
|||
return !symbols.loading;
|
||||
}
|
||||
|
||||
export function getFramework(state: OuterState, source: Source): ?string {
|
||||
const symbols = getSymbols(state, source);
|
||||
if (symbols && !symbols.loading) {
|
||||
return symbols.framework;
|
||||
}
|
||||
}
|
||||
|
||||
export function isSymbolsLoading(state: OuterState, source: ?Source): boolean {
|
||||
const symbols = getSymbols(state, source);
|
||||
if (!symbols) {
|
||||
|
@ -166,15 +163,6 @@ export function getPreview(state: OuterState) {
|
|||
return state.ast.preview;
|
||||
}
|
||||
|
||||
const emptySourceMetaData = {};
|
||||
export function getSourceMetaData(state: OuterState, sourceId: string) {
|
||||
return state.ast.sourceMetaData[sourceId] || emptySourceMetaData;
|
||||
}
|
||||
|
||||
export function hasSourceMetaData(state: OuterState, sourceId: string) {
|
||||
return state.ast.sourceMetaData[sourceId];
|
||||
}
|
||||
|
||||
export function getInScopeLines(state: OuterState) {
|
||||
return state.ast.inScopeLines;
|
||||
}
|
||||
|
|
|
@ -50,4 +50,4 @@ export type { SourcesMap, SourcesMapByThread } from "./sources";
|
|||
export type { ActiveSearchType, OrientationType } from "./ui";
|
||||
export type { BreakpointsMap, XHRBreakpointsList } from "./breakpoints";
|
||||
export type { Command } from "./pause";
|
||||
export type { SourceMetaDataMap, SourceMetaDataType } from "./ast";
|
||||
export type { Symbols } from "./ast";
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
import { getSymbols, getSource, getSelectedFrame, getCurrentThread } from ".";
|
||||
import { findClosestClass } from "../utils/ast";
|
||||
import { getSourceMetaData } from "../reducers/ast";
|
||||
|
||||
import type { State } from "../reducers/types";
|
||||
|
||||
|
@ -24,7 +23,7 @@ export function inComponent(state: State) {
|
|||
|
||||
const symbols = getSymbols(state, source);
|
||||
|
||||
if (!symbols) {
|
||||
if (!symbols || symbols.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -33,13 +32,7 @@ export function inComponent(state: State) {
|
|||
return null;
|
||||
}
|
||||
|
||||
const sourceMetaData = getSourceMetaData(state, source.id);
|
||||
|
||||
if (!sourceMetaData || !sourceMetaData.framework) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inReactFile = sourceMetaData.framework == "React";
|
||||
const inReactFile = symbols.framework == "React";
|
||||
const { parent } = closestClass;
|
||||
const isComponent = parent && parent.name.includes("Component");
|
||||
|
||||
|
|
|
@ -22,8 +22,7 @@ import { getURL, getFileExtension } from "./sources-tree";
|
|||
import { prefs, features } from "./prefs";
|
||||
|
||||
import type { Source, SourceLocation, JsSource } from "../types";
|
||||
import type { SourceMetaDataType } from "../reducers/ast";
|
||||
import type { SymbolDeclarations } from "../workers/parser";
|
||||
import type { Symbols } from "../reducers/types";
|
||||
|
||||
type transformUrlCallback = string => string;
|
||||
|
||||
|
@ -316,7 +315,7 @@ export function getSourceLineCount(source: Source) {
|
|||
|
||||
export function getMode(
|
||||
source: Source,
|
||||
symbols?: SymbolDeclarations
|
||||
symbols?: Symbols
|
||||
): { name: string, base?: Object } {
|
||||
if (source.isWasm) {
|
||||
return { name: "text" };
|
||||
|
@ -430,10 +429,7 @@ export function getTextAtPosition(source: ?Source, location: SourceLocation) {
|
|||
return lineText.slice(column, column + 100).trim();
|
||||
}
|
||||
|
||||
export function getSourceClassnames(
|
||||
source: Object,
|
||||
sourceMetaData?: SourceMetaDataType
|
||||
) {
|
||||
export function getSourceClassnames(source: Object, symbols?: Symbols) {
|
||||
// Conditionals should be ordered by priority of icon!
|
||||
const defaultClassName = "file";
|
||||
|
||||
|
@ -449,8 +445,8 @@ export function getSourceClassnames(
|
|||
return "blackBox";
|
||||
}
|
||||
|
||||
if (sourceMetaData && sourceMetaData.framework) {
|
||||
return sourceMetaData.framework.toLowerCase();
|
||||
if (symbols && !symbols.loading && symbols.framework) {
|
||||
return symbols.framework.toLowerCase();
|
||||
}
|
||||
|
||||
return sourceTypes[getFileExtension(source)] || defaultClassName;
|
||||
|
|
|
@ -30,7 +30,8 @@ const defaultSymbolDeclarations = {
|
|||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
loading: false
|
||||
loading: false,
|
||||
framework: undefined
|
||||
};
|
||||
|
||||
describe("sources", () => {
|
||||
|
|
|
@ -5,26 +5,22 @@
|
|||
// @flow
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import { getSymbols } from "./getSymbols";
|
||||
|
||||
export function getFramework(sourceId: string): ?string {
|
||||
const sourceSymbols = getSymbols(sourceId);
|
||||
import type { SymbolDeclarations } from "./getSymbols";
|
||||
|
||||
if (isReactComponent(sourceSymbols)) {
|
||||
export function getFramework(symbols: SymbolDeclarations): ?string {
|
||||
if (isReactComponent(symbols)) {
|
||||
return "React";
|
||||
}
|
||||
if (isAngularComponent(sourceSymbols)) {
|
||||
if (isAngularComponent(symbols)) {
|
||||
return "Angular";
|
||||
}
|
||||
if (isVueComponent(sourceSymbols)) {
|
||||
if (isVueComponent(symbols)) {
|
||||
return "Vue";
|
||||
}
|
||||
}
|
||||
|
||||
// React
|
||||
|
||||
function isReactComponent(sourceSymbols) {
|
||||
const { imports, classes, callExpressions } = sourceSymbols;
|
||||
function isReactComponent({ imports, classes, callExpressions }) {
|
||||
return (
|
||||
importsReact(imports) ||
|
||||
requiresReact(callExpressions) ||
|
||||
|
@ -58,20 +54,14 @@ function extendsReactComponent(classes) {
|
|||
);
|
||||
}
|
||||
|
||||
// Angular
|
||||
|
||||
const isAngularComponent = sourceSymbols => {
|
||||
const { memberExpressions } = sourceSymbols;
|
||||
function isAngularComponent({ memberExpressions }) {
|
||||
return memberExpressions.some(
|
||||
item =>
|
||||
item.expression == "angular.controller" ||
|
||||
item.expression == "angular.module"
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
// Vue
|
||||
|
||||
const isVueComponent = sourceSymbols => {
|
||||
const { identifiers } = sourceSymbols;
|
||||
function isVueComponent({ identifiers }) {
|
||||
return identifiers.some(identifier => identifier.name == "Vue");
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
|
||||
import { inferClassName } from "./utils/inferClassName";
|
||||
import getFunctionName from "./utils/getFunctionName";
|
||||
import { getFramework } from "./frameworks";
|
||||
|
||||
import type { SimplePath, Node, TraversalAncestors } from "./utils/simple-path";
|
||||
|
||||
|
@ -80,6 +81,7 @@ export type SymbolDeclarations = {|
|
|||
literals: Array<IdentifierDeclaration>,
|
||||
hasJsx: boolean,
|
||||
hasTypes: boolean,
|
||||
framework: ?string,
|
||||
loading: false
|
||||
|};
|
||||
|
||||
|
@ -276,7 +278,8 @@ function extractSymbols(sourceId): SymbolDeclarations {
|
|||
literals: [],
|
||||
hasJsx: false,
|
||||
hasTypes: false,
|
||||
loading: false
|
||||
loading: false,
|
||||
framework: undefined
|
||||
};
|
||||
|
||||
const state = {
|
||||
|
@ -299,6 +302,7 @@ function extractSymbols(sourceId): SymbolDeclarations {
|
|||
// comments are extracted separately from the AST
|
||||
symbols.comments = getComments(ast);
|
||||
symbols.identifiers = getUniqueIdentifiers(symbols.identifiers);
|
||||
symbols.framework = getFramework(symbols);
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols call expression 1`] = `
|
||||
|
@ -151,7 +153,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols call sites 1`] = `
|
||||
|
@ -197,7 +201,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols class 1`] = `
|
||||
|
@ -249,7 +255,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols component 1`] = `
|
||||
|
@ -411,7 +419,9 @@ hasJsx: true
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols destruct 1`] = `
|
||||
|
@ -500,7 +510,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols es6 1`] = `
|
||||
|
@ -538,7 +550,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols expression 1`] = `
|
||||
|
@ -719,7 +733,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols finds symbols in an html file 1`] = `
|
||||
|
@ -799,7 +815,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols flow 1`] = `
|
||||
|
@ -839,7 +857,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: true
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols func 1`] = `
|
||||
|
@ -922,7 +942,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols function names 1`] = `
|
||||
|
@ -1047,7 +1069,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols jsx 1`] = `
|
||||
|
@ -1085,7 +1109,9 @@ hasJsx: true
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols math 1`] = `
|
||||
|
@ -1138,7 +1164,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols object expressions 1`] = `
|
||||
|
@ -1220,7 +1248,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols proto 1`] = `
|
||||
|
@ -1279,7 +1309,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols react component 1`] = `
|
||||
|
@ -1317,7 +1349,9 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: React"
|
||||
`;
|
||||
|
||||
exports[`Parser.getSymbols var 1`] = `
|
||||
|
@ -1385,5 +1419,7 @@ hasJsx: false
|
|||
|
||||
hasTypes: false
|
||||
|
||||
loading: false"
|
||||
loading: false
|
||||
|
||||
framework: undefined"
|
||||
`;
|
||||
|
|
|
@ -4,58 +4,54 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import { getFramework } from "../frameworks";
|
||||
import { getSource, getOriginalSource } from "./helpers";
|
||||
import { getSymbols } from "../getSymbols";
|
||||
import { getOriginalSource } from "./helpers";
|
||||
import { setSource } from "../sources";
|
||||
import cases from "jest-in-case";
|
||||
|
||||
describe("Parser.frameworks", () => {
|
||||
describe("no framework", () => {
|
||||
it("is undefined when no framework", () => {
|
||||
const source = getOriginalSource("frameworks/plainJavascript");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not get confused with angular (#6833)", () => {
|
||||
const source = getOriginalSource("frameworks/angular1FalsePositive");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("react", () => {
|
||||
it("recognizes ES6 React component", () => {
|
||||
const source = getOriginalSource("frameworks/reactComponent");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBe("React");
|
||||
});
|
||||
|
||||
it("recognizes ES5 React component", () => {
|
||||
const source = getSource("frameworks/reactComponentEs5");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBe("React");
|
||||
});
|
||||
});
|
||||
|
||||
describe("angular 1.*", () => {
|
||||
it("recognizes Angular 1 module", () => {
|
||||
const source = getOriginalSource("frameworks/angular1Module");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBe("Angular");
|
||||
});
|
||||
});
|
||||
|
||||
describe("vue", () => {
|
||||
it("recognizes declarative Vue file", () => {
|
||||
const source = getOriginalSource("frameworks/vueFileDeclarative");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBe("Vue");
|
||||
});
|
||||
|
||||
it("recognizes component Vue file", () => {
|
||||
const source = getOriginalSource("frameworks/vueFileComponent");
|
||||
setSource(source);
|
||||
expect(getFramework(source.id)).toBe("Vue");
|
||||
});
|
||||
});
|
||||
});
|
||||
cases(
|
||||
"Parser.getFramework",
|
||||
({ name, file, value }) => {
|
||||
const source = getOriginalSource("frameworks/plainJavascript");
|
||||
setSource(source);
|
||||
const symbols = getSymbols(source.id);
|
||||
expect(symbols.framework).toBeUndefined();
|
||||
},
|
||||
[
|
||||
{
|
||||
name: "is undefined when no framework",
|
||||
file: "frameworks/plainJavascript",
|
||||
value: undefined
|
||||
},
|
||||
{
|
||||
name: "does not get confused with angular (#6833)",
|
||||
file: "frameworks/angular1FalsePositive",
|
||||
value: undefined
|
||||
},
|
||||
{
|
||||
name: "recognizes ES6 React component",
|
||||
file: "frameworks/reactComponent",
|
||||
value: "React"
|
||||
},
|
||||
{
|
||||
name: "recognizes ES5 React component",
|
||||
file: "frameworks/reactComponentEs5",
|
||||
value: "React"
|
||||
},
|
||||
{
|
||||
name: "recognizes Angular 1 module",
|
||||
file: "frameworks/angular1Module",
|
||||
value: "Angular"
|
||||
},
|
||||
{
|
||||
name: "recognizes declarative Vue file",
|
||||
file: "frameworks/vueFileDeclarative",
|
||||
value: "Vue"
|
||||
},
|
||||
{
|
||||
name: "recognizes component Vue file",
|
||||
file: "frameworks/vueFileComponent",
|
||||
value: "Vue"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
|
|
@ -40,15 +40,24 @@ function summarize(symbol) {
|
|||
return `${loc} ${expression} ${name}${params} ${klass} ${names} ${values} ${index}`.trim(); // eslint-disable-line max-len
|
||||
}
|
||||
const bools = ["hasJsx", "hasTypes", "loading"];
|
||||
const strings = ["framework"];
|
||||
function formatBool(name, symbols) {
|
||||
return `${name}: ${symbols[name] ? "true" : "false"}`;
|
||||
}
|
||||
|
||||
function formatString(name, symbols) {
|
||||
return `${name}: ${symbols[name]}`;
|
||||
}
|
||||
|
||||
function formatKey(name: string, symbols: any) {
|
||||
if (bools.includes(name)) {
|
||||
return formatBool(name, symbols);
|
||||
}
|
||||
|
||||
if (strings.includes(name)) {
|
||||
return formatString(name, symbols);
|
||||
}
|
||||
|
||||
return `${name}:\n${symbols[name].map(summarize).join("\n")}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,6 @@ function waitForSelectedSource(dbg, url) {
|
|||
const {
|
||||
getSelectedSource,
|
||||
hasSymbols,
|
||||
hasSourceMetaData,
|
||||
hasBreakpointPositions
|
||||
} = dbg.selectors;
|
||||
|
||||
|
@ -236,9 +235,9 @@ function waitForSelectedSource(dbg, url) {
|
|||
return false;
|
||||
}
|
||||
|
||||
return hasSymbols(state, source) &&
|
||||
hasSourceMetaData( state, source.id) &&
|
||||
hasBreakpointPositions(state, source.id);
|
||||
return (
|
||||
hasSymbols(state, source) && hasBreakpointPositions(state, source.id)
|
||||
);
|
||||
},
|
||||
"selected source"
|
||||
);
|
||||
|
|
|
@ -100,15 +100,12 @@ function waitForText(dbg, url, text) {
|
|||
}, "text is visible");
|
||||
}
|
||||
|
||||
function waitForMetaData(dbg) {
|
||||
function waitForSymbols(dbg) {
|
||||
return waitUntil(
|
||||
() => {
|
||||
const state = dbg.store.getState();
|
||||
const source = dbg.selectors.getSelectedSource(state);
|
||||
// wait for metadata -- this involves parsing the file to determine its type.
|
||||
// if the object is empty, the data has not yet loaded
|
||||
const metaData = dbg.selectors.getSourceMetaData(state, source.id);
|
||||
return !!Object.keys(metaData).length;
|
||||
return dbg.selectors.hasSymbols(state, source);
|
||||
},
|
||||
"has file metadata"
|
||||
);
|
||||
|
@ -219,7 +216,7 @@ async function openDebuggerAndLog(label, expected) {
|
|||
await waitForSource(dbg, expected.sourceURL);
|
||||
await selectSource(dbg, expected.file);
|
||||
await waitForText(dbg, expected.file, expected.text);
|
||||
await waitForMetaData(dbg);
|
||||
await waitForSymbols(dbg);
|
||||
};
|
||||
|
||||
const toolbox = await openToolboxAndLog(label + ".jsdebugger", "jsdebugger", onLoad);
|
||||
|
@ -234,7 +231,7 @@ async function reloadDebuggerAndLog(label, toolbox, expected) {
|
|||
await waitForDispatch(dbg, "NAVIGATE");
|
||||
await waitForSources(dbg, expected.sources);
|
||||
await waitForText(dbg, expected.file, expected.text);
|
||||
await waitForMetaData(dbg);
|
||||
await waitForSymbols(dbg);
|
||||
};
|
||||
await reloadPageAndLog(`${label}.jsdebugger`, toolbox, onReload);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче