LogBox - Press to open code frame file

Summary:
This diff adds the ability to press the file name of a code frame to open the file in your editor.

Note: I re-worked the frame location to extract the frame row and column at parse time so that we don't need to do any clowny regexes down stream.

Changelog: [Internal]

Reviewed By: cpojer

Differential Revision: D18358283

fbshipit-source-id: 705e07d229c66ecfd225a8fb65ef2f78b5034c9c
This commit is contained in:
Rick Hanlon authored and Facebook Github Bot committed 2019-11-07 09:11:59 -08:00
1 parent 83401adeae
commit 7ad862eaba
8 files changed
+170 -83

No files matched your search

@@ -26,7 +26,7 @@ function getLogBoxLog() {
[{component: 'LogBoxLog', location: 'LogBoxLog.js:1'}],
{
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: '<code frame>',
},
);
@@ -70,7 +70,7 @@ describe('LogBoxLog', () => {
]);
expect(log.codeFrame).toEqual({
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: '<code frame>',
});
});
@@ -178,7 +178,7 @@ describe('parseLogBoxLog', () => {
level: 'syntax',
codeFrame: {
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: ` 197 | });
198 |
> 199 | export default CrashReactApp;
@@ -190,7 +190,7 @@ describe('parseLogBoxLog', () => {
substitutions: [],
},
stack: [],
category: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js (199:0)',
category: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js-199-0',
});
});
+11 -5
View File
@@ -19,7 +19,10 @@ import type {Stack} from './LogBoxSymbolication';
export type Category = string;
export type CodeFrame = $ReadOnly<{|
content: string,
location: string,
location: {
row: number,
column: number,
},
fileName: string,
|}>;
export type Message = $ReadOnly<{|
@@ -146,7 +149,7 @@ export function parseLogBoxException(
const message =
error.originalMessage != null ? error.originalMessage : 'Unknown';
const match = message.match(
/(?:TransformError )?(?:SyntaxError: )(.*): (.*) (.*)\n\n([\s\S]+)/,
/(?:TransformError )?(?:SyntaxError: )(.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/,
);
if (!match) {
@@ -161,20 +164,23 @@ export function parseLogBoxException(
};
}
const [fileName, content, location, codeFrame] = match.slice(1);
const [fileName, content, row, column, codeFrame] = match.slice(1);
return {
level: 'syntax',
stack: [],
codeFrame: {
fileName,
location,
location: {
row: parseInt(row, 10),
column: parseInt(column, 10),
},
content: codeFrame,
},
message: {
content,
substitutions: [],
},
category: `${fileName} ${location}`,
category: `${fileName}-${row}-${column}`,
};
}
+49 -31
View File
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @flow
* @format
*/
@@ -17,6 +17,9 @@ import Text from '../../Text/Text';
import View from '../../Components/View/View';
import * as LogBoxStyle from './LogBoxStyle';
import type {CodeFrame} from '../Data/parseLogBoxLog';
import LogBoxButton from './LogBoxButton';
import openFileInEditor from '../../Core/Devtools/openFileInEditor';
import stripAnsi from 'strip-ansi';
type Props = $ReadOnly<{|
codeFrame: ?CodeFrame,
@@ -38,30 +41,55 @@ function LogBoxInspectorCodeFrame(props: Props): React.Node {
}
return (
<View style={metaStyles.section}>
<View style={metaStyles.box}>
<ScrollView horizontal>
<Text style={metaStyles.headingText}>{codeFrame.content}</Text>
</ScrollView>
<View style={styles.section}>
<View style={styles.heading}>
<Text style={styles.headingText}>Location</Text>
</View>
<View style={styles.box}>
<View style={styles.frame}>
<ScrollView horizontal>
<Text style={styles.content}>{stripAnsi(codeFrame.content)}</Text>
</ScrollView>
</View>
<LogBoxButton
backgroundColor={{
default: 'transparent',
pressed: LogBoxStyle.getBackgroundDarkColor(1),
}}
style={styles.button}
onPress={() => {
openFileInEditor(codeFrame.fileName, codeFrame.location?.row ?? 0);
}}>
<Text style={styles.fileText}>
{getFileName()} ({codeFrame.location.row}:
{codeFrame.location.column})
</Text>
</LogBoxButton>
</View>
<Text style={metaStyles.fileText}>
{getFileName()} {codeFrame.location}
</Text>
</View>
);
}
const metaStyles = StyleSheet.create({
const styles = StyleSheet.create({
section: {
marginTop: 30,
marginBottom: 20,
marginTop: 20,
marginBottom: 10,
},
box: {
backgroundColor: LogBoxStyle.getBackgroundColor(),
marginLeft: 10,
marginRight: 10,
marginTop: 5,
borderRadius: 3,
},
frame: {
padding: 10,
borderBottomColor: LogBoxStyle.getTextColor(0.1),
borderBottomWidth: 1,
},
button: {
paddingTop: 10,
paddingBottom: 10,
},
heading: {
alignItems: 'center',
@@ -70,6 +98,14 @@ const metaStyles = StyleSheet.create({
marginBottom: 10,
},
headingText: {
color: LogBoxStyle.getTextColor(1),
flex: 1,
fontSize: 20,
fontWeight: '600',
includeFontPadding: false,
lineHeight: 20,
},
content: {
color: LogBoxStyle.getTextColor(1),
flex: 1,
fontSize: 12,
@@ -83,27 +119,9 @@ const metaStyles = StyleSheet.create({
flex: 1,
fontSize: 12,
includeFontPadding: false,
lineHeight: 20,
lineHeight: 16,
fontFamily: Platform.select({android: 'monospace', ios: 'Menlo'}),
},
body: {
paddingLeft: 25,
paddingRight: 25,
paddingBottom: 100,
flexDirection: 'row',
justifyContent: 'space-between',
},
bodyItem: {
flex: 0,
},
bodyText: {
color: LogBoxStyle.getTextColor(1),
fontSize: 14,
includeFontPadding: false,
lineHeight: 20,
flex: 0,
flexGrow: 0,
},
});
export default LogBoxInspectorCodeFrame;
@@ -304,7 +304,7 @@ describe('LogBoxContainer', () => {
{
fileName:
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: ` 197 | });
198 |
> 199 | export default CrashReactApp;
@@ -324,7 +324,7 @@ describe('LogBoxContainer', () => {
{
fileName:
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: ` 197 | });
198 |
> 199 | export default CrashReactApp;
@@ -361,7 +361,7 @@ describe('LogBoxContainer', () => {
{
fileName:
'/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: ` 197 | });
198 |
> 199 | export default CrashReactApp;
@@ -29,7 +29,7 @@ describe('LogBoxInspectorCodeFrame', () => {
<LogBoxInspectorCodeFrame
codeFrame={{
fileName: '/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js',
location: '(199:0)',
location: {row: 199, column: 0},
content: ` 197 | });
198 |
> 199 | export default CrashReactApp;
@@ -298,7 +298,10 @@ exports[`LogBoxContainer should render most recent syntax error 1`] = `
| ^
200 |",
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
"location": "(199:0)",
"location": Object {
"column": 0,
"row": 199,
},
},
"componentStack": Array [],
"count": 1,
@@ -323,7 +326,10 @@ exports[`LogBoxContainer should render most recent syntax error 1`] = `
| ^
200 |",
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
"location": "(199:0)",
"location": Object {
"column": 0,
"row": 199,
},
},
"componentStack": Array [],
"count": 1,
@@ -378,7 +384,10 @@ exports[`LogBoxContainer should render syntax error even when disabled 1`] = `
| ^
200 |",
"fileName": "/path/to/RKJSModules/Apps/CrashReact/CrashReactApp.js",
"location": "(199:0)",
"location": Object {
"column": 0,
"row": 199,
},
},
"componentStack": Array [],
"count": 1,
@@ -4,11 +4,36 @@ exports[`LogBoxInspectorCodeFrame should render a code frame 1`] = `
<View
style={
Object {
"marginBottom": 20,
"marginTop": 30,
"marginBottom": 10,
"marginTop": 20,
}
}
>
<View
style={
Object {
"alignItems": "center",
"flexDirection": "row",
"marginBottom": 10,
"paddingHorizontal": 12,
}
}
>
<Text
style={
Object {
"color": "rgba(255, 255, 255, 1)",
"flex": 1,
"fontSize": 20,
"fontWeight": "600",
"includeFontPadding": false,
"lineHeight": 20,
}
}
>
Location
</Text>
</View>
<View
style={
Object {
@@ -16,50 +41,79 @@ exports[`LogBoxInspectorCodeFrame should render a code frame 1`] = `
"borderRadius": 3,
"marginLeft": 10,
"marginRight": 10,
"padding": 10,
"marginTop": 5,
}
}
>
<ScrollViewMock
horizontal={true}
>
<Text
style={
Object {
"color": "rgba(255, 255, 255, 1)",
"flex": 1,
"fontFamily": "Menlo",
"fontSize": 12,
"includeFontPadding": false,
"lineHeight": 20,
}
<View
style={
Object {
"borderBottomColor": "rgba(255, 255, 255, 0.1)",
"borderBottomWidth": 1,
"padding": 10,
}
}
>
<ScrollViewMock
horizontal={true}
>
197 | });
<Text
style={
Object {
"color": "rgba(255, 255, 255, 1)",
"flex": 1,
"fontFamily": "Menlo",
"fontSize": 12,
"includeFontPadding": false,
"lineHeight": 20,
}
}
>
197 | });
198 |
&gt; 199 | export default CrashReactApp;
| ^
200 |
</Text>
</ScrollViewMock>
</View>
<Text
style={
Object {
"color": "rgba(255, 255, 255, 0.5)",
"flex": 1,
"fontFamily": "Menlo",
"fontSize": 12,
"includeFontPadding": false,
"lineHeight": 20,
"textAlign": "center",
</Text>
</ScrollViewMock>
</View>
<LogBoxButton
backgroundColor={
Object {
"default": "transparent",
"pressed": "rgba(34, 34, 34, 1)",
}
}
}
>
CrashReactApp.js
(199:0)
</Text>
onPress={[Function]}
style={
Object {
"paddingBottom": 10,
"paddingTop": 10,
}
}
>
<Text
style={
Object {
"color": "rgba(255, 255, 255, 0.5)",
"flex": 1,
"fontFamily": "Menlo",
"fontSize": 12,
"includeFontPadding": false,
"lineHeight": 16,
"textAlign": "center",
}
}
>
CrashReactApp.js
(
199
:
0
)
</Text>
</LogBoxButton>
</View>
</View>
`;