( context: ?Context, pushMapping: RangeMapping => void, )
| 148 | } |
| 149 | |
| 150 | function getFunctionMapVisitor( |
| 151 | context: ?Context, |
| 152 | pushMapping: RangeMapping => void, |
| 153 | ): FunctionMapVisitor { |
| 154 | const nameStack: Array<{loc: BabelNodeSourceLocation, name: string}> = []; |
| 155 | let tailPos = {line: 1, column: 0}; |
| 156 | let tailName: null | string = null; |
| 157 | |
| 158 | function advanceToPos(pos: {column: number, line: number}) { |
| 159 | if (tailPos && positionGreater(pos, tailPos)) { |
| 160 | const name = nameStack[0].name; // We always have at least Program |
| 161 | if (name !== tailName) { |
| 162 | pushMapping({ |
| 163 | name, |
| 164 | start: {line: tailPos.line, column: tailPos.column}, |
| 165 | }); |
| 166 | tailName = name; |
| 167 | } |
| 168 | } |
| 169 | tailPos = pos; |
| 170 | } |
| 171 | |
| 172 | function pushFrame(name: string, loc: BabelNodeSourceLocation) { |
| 173 | advanceToPos(loc.start); |
| 174 | nameStack.unshift({name, loc}); |
| 175 | } |
| 176 | |
| 177 | function popFrame() { |
| 178 | const top = nameStack[0]; |
| 179 | if (top) { |
| 180 | const {loc} = top; |
| 181 | advanceToPos(loc.end); |
| 182 | nameStack.shift(); |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | if (!context) { |
| 187 | context = {}; |
| 188 | } |
| 189 | |
| 190 | const basename = context.filename |
| 191 | ? fsPath.basename(context.filename).replace(/\..+$/, '') |
| 192 | : null; |
| 193 | |
| 194 | return { |
| 195 | enter(path) { |
| 196 | let name = getNameForPath(path); |
| 197 | if (basename) { |
| 198 | name = removeNamePrefix(name, basename); |
| 199 | } |
| 200 | pushFrame(name, nullthrows(path.node.loc)); |
| 201 | }, |
| 202 | |
| 203 | exit(path) { |
| 204 | popFrame(); |
| 205 | }, |
| 206 | }; |
| 207 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…