Skip to content

Commit

Permalink
Strip function arguments from Copy -> Function Name (firefox-devtools…
Browse files Browse the repository at this point in the history
  • Loading branch information
brisad authored and julienw committed Jun 29, 2017
1 parent 3537da7 commit 578f02d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/components/calltree/ProfileCallTreeContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ContextMenu, MenuItem, SubMenu } from 'react-contextmenu';
import actions from '../../actions';
import { connect } from 'react-redux';
import { selectedThreadSelectors } from '../../reducers/profile-view';
import { stripFunctionArguments } from '../../profile-logic/function-info';
import copy from 'copy-to-clipboard';

import type { IndexIntoFuncStackTable, FuncStackInfo } from '../../types/profile-derived';
Expand Down Expand Up @@ -35,7 +36,8 @@ class ProfileCallTreeContextMenu extends PureComponent {

const funcIndex = funcStackTable.func[selectedFuncStack];
const stringIndex = funcTable.name[funcIndex];
const name = stringTable.getString(stringIndex);
const functionCall = stringTable.getString(stringIndex);
const name = stripFunctionArguments(functionCall);
copy(name);
}

Expand Down
30 changes: 30 additions & 0 deletions src/profile-logic/function-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,33 @@ export function getFunctionInfo(fullName) {
getJSFunctionInfo(fullName) ||
getFallbackFunctionInfo(fullName);
}

/**
* Strip any function arguments from the given string.
*
* If the function fails to determine that there are any parentheses to strip
* it will return the original string.
*/
export function stripFunctionArguments(functionCall) {
// Remove known data that can appear at the end of the string
const s = functionCall.replace(/ \[clone [^]+\]$/, '').replace(/ const$/, '');
if (s[s.length - 1] !== ')') {
return functionCall;
}

// Start from the right parenthesis at the end of the string and
// then iterate towards the beginning until we find the matching
// left parenthesis.
let depth = 0;
for (let i = s.length - 1; i > 0; i--) {
if (s[i] === ')') {
depth++;
} else if (s[i] === '(') {
depth--;
if (depth === 0) {
return functionCall.substr(0, i);
}
}
}
return functionCall;
}
22 changes: 22 additions & 0 deletions src/test/unit/function-info.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* 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 { stripFunctionArguments } from '../../profile-logic/function-info';

describe('get-function-name', function () {
it('should strip the function arguments', function () {
expect(stripFunctionArguments('ns::fn()')).toEqual('ns::fn');
expect(stripFunctionArguments('ns::fn(bool (*)(JS::Handle<JSObject*>))')).toEqual('ns::fn');
expect(stripFunctionArguments('Bar* ns::fn<(Foo)0>(void const*, unsigned int)')).toEqual('Bar* ns::fn<(Foo)0>');
expect(stripFunctionArguments('ns::fn(bool, bool) [clone .part.123]')).toEqual('ns::fn');
expect(stripFunctionArguments('ns::fn() const')).toEqual('ns::fn');
expect(stripFunctionArguments('ns::fn() const [clone .part.123]')).toEqual('ns::fn');
});
it('should do nothing if not ending with parentheses', function () {
expect(stripFunctionArguments('ns::fn [clone .part.123]')).toEqual('ns::fn [clone .part.123]');
});
it('should do nothing if not a function call', function () {
expect(stripFunctionArguments('(root)')).toEqual('(root)');
});
});

0 comments on commit 578f02d

Please sign in to comment.