Advertisement
Guest User

Untitled

a guest
Jun 25th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JSON 15.74 KB | None | 0 0
  1. ["webpack:///C:/src/github.com/janodvarko/debugger.html/src/utils/pause/mapScopes/locColumn.js",{"id":"server2.conn2.child1/source26/originalSource-d8b8cf0062e8403007261efaebc48a26","url":"webpack:///C:/src/github.com/janodvarko/debugger.html/src/utils/pause/mapScopes/index.js","isBlackBoxed":false,"isPrettyPrinted":false,"isWasm":false,"text":"/* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */\n\n// @flow\n\nimport {\n  getScopes,\n  type SourceScope,\n  type BindingData,\n  type BindingLocation\n} from \"../../../workers/parser\";\nimport type { RenderableScope } from \"../scopes/getScope\";\nimport { locColumn } from \"./locColumn\";\nimport {\n  loadRangeMetadata,\n  findMatchingRange,\n  type MappedOriginalRange\n} from \"./rangeMetadata\";\n\n// eslint-disable-next-line max-len\nimport {\n  findGeneratedBindingForImportBinding,\n  findGeneratedBindingForStandardBinding,\n  findGeneratedBindingForNormalDeclaration,\n  findGeneratedBindingForImportDeclaration,\n  type GeneratedDescriptor\n} from \"./findGeneratedBindingFromPosition\";\nimport {\n  buildGeneratedBindingList,\n  type GeneratedBindingLocation\n} from \"./buildGeneratedBindingList\";\n\nimport { log } from \"../../log\";\nimport type {\n  Position,\n  Frame,\n  Scope,\n  Source,\n  BindingContents,\n  ScopeBindings\n} from \"../../../types\";\n\nexport type OriginalScope = RenderableScope;\n\nexport async function buildMappedScopes(\n  source: Source,\n  frame: Frame,\n  scopes: Scope,\n  sourceMaps: any,\n  client: any\n): Promise<?{\n  mappings: {\n    [string]: string\n  },\n  scope: OriginalScope\n}> {\n  const originalAstScopes = await getScopes(frame.location);\n  const generatedAstScopes = await getScopes(frame.generatedLocation);\n\n  if (!originalAstScopes || !generatedAstScopes) {\n    return null;\n  }\n\n  const generatedAstBindings = buildGeneratedBindingList(\n    scopes,\n    generatedAstScopes,\n    frame.this\n  );\n\n  const originalRanges = await loadRangeMetadata(\n    source,\n    frame,\n    originalAstScopes,\n    sourceMaps\n  );\n\n  const {\n    mappedOriginalScopes,\n    expressionLookup\n  } = await mapOriginalBindingsToGenerated(\n    source,\n    originalRanges,\n    originalAstScopes,\n    generatedAstBindings,\n    client,\n    sourceMaps\n  );\n\n  const mappedGeneratedScopes = generateClientScope(\n    scopes,\n    mappedOriginalScopes\n  );\n\n  return isReliableScope(mappedGeneratedScopes)\n    ? { mappings: expressionLookup, scope: mappedGeneratedScopes }\n    : null;\n}\n\nasync function mapOriginalBindingsToGenerated(\n  source: Source,\n  originalRanges: Array<MappedOriginalRange>,\n  originalAstScopes,\n  generatedAstBindings,\n  client,\n  sourceMaps\n) {\n  const expressionLookup = {};\n  const mappedOriginalScopes = [];\n\n  const cachedSourceMaps = batchScopeMappings(\n    originalAstScopes,\n    source,\n    sourceMaps\n  );\n\n  for (const item of originalAstScopes) {\n    const generatedBindings = {};\n\n    for (const name of Object.keys(item.bindings)) {\n      const binding = item.bindings[name];\n\n      const result = await findGeneratedBinding(\n        cachedSourceMaps,\n        client,\n        source,\n        name,\n        binding,\n        originalRanges,\n        generatedAstBindings\n      );\n\n      if (result) {\n        generatedBindings[name] = result.grip;\n\n        if (\n          binding.refs.length !== 0 &&\n          // These are assigned depth-first, so we don't want shadowed\n          // bindings in parent scopes overwriting the expression.\n          !Object.prototype.hasOwnProperty.call(expressionLookup, name)\n        ) {\n          expressionLookup[name] = result.expression;\n        }\n      }\n    }\n\n    mappedOriginalScopes.push({\n      ...item,\n      generatedBindings\n    });\n  }\n\n  return {\n    mappedOriginalScopes,\n    expressionLookup\n  };\n}\n\n/**\n * Consider a scope and its parents reliable if the vast majority of its\n * bindings were successfully mapped to generated scope bindings.\n */\nfunction isReliableScope(scope: OriginalScope): boolean {\n  let totalBindings = 0;\n  let unknownBindings = 0;\n\n  for (let s = scope; s; s = s.parent) {\n    const vars = (s.bindings && s.bindings.variables) || {};\n    for (const key of Object.keys(vars)) {\n      const binding = vars[key];\n\n      totalBindings += 1;\n      if (\n        binding.value &&\n        typeof binding.value === \"object\" &&\n        (binding.value.type === \"unscoped\" || binding.value.type === \"unmapped\")\n      ) {\n        unknownBindings += 1;\n      }\n    }\n  }\n\n  // As determined by fair dice roll.\n  return totalBindings === 0 || unknownBindings / totalBindings < 0.1;\n}\n\nfunction batchScopeMappings(\n  originalAstScopes: Array<SourceScope>,\n  source: Source,\n  sourceMaps: any\n) {\n  const precalculatedRanges = new Map();\n  const precalculatedLocations = new Map();\n\n  // Explicitly dispatch all of the sourcemap requests synchronously up front so\n  // that they will be batched into a single request for the worker to process.\n  for (const item of originalAstScopes) {\n    for (const name of Object.keys(item.bindings)) {\n      for (const ref of item.bindings[name].refs) {\n        const locs = [ref];\n        if (ref.type !== \"ref\") {\n          locs.push(ref.declaration);\n        }\n\n        for (const loc of locs) {\n          precalculatedRanges.set(\n            buildLocationKey(loc.start),\n            sourceMaps.getGeneratedRanges(loc.start, source)\n          );\n          precalculatedLocations.set(\n            buildLocationKey(loc.start),\n            sourceMaps.getGeneratedLocation(loc.start, source)\n          );\n          precalculatedLocations.set(\n            buildLocationKey(loc.end),\n            sourceMaps.getGeneratedLocation(loc.end, source)\n          );\n        }\n      }\n    }\n  }\n\n  return {\n    async getGeneratedRanges(pos, s) {\n      const key = buildLocationKey(pos);\n\n      if (s !== source || !precalculatedRanges.has(key)) {\n        log(\"Bad precalculated mapping\");\n        return sourceMaps.getGeneratedRanges(pos, s);\n      }\n      return precalculatedRanges.get(key);\n    },\n    async getGeneratedLocation(pos, s) {\n      const key = buildLocationKey(pos);\n\n      if (s !== source || !precalculatedLocations.has(key)) {\n        log(\"Bad precalculated mapping\");\n        return sourceMaps.getGeneratedLocation(pos, s);\n      }\n      return precalculatedLocations.get(key);\n    }\n  };\n}\nfunction buildLocationKey(loc: Position): string {\n  return `${loc.line}:${locColumn(loc)}`;\n}\n\nfunction generateClientScope(\n  scopes: Scope,\n  originalScopes: Array<SourceScope & { generatedBindings: ScopeBindings }>\n): OriginalScope {\n  // Pull the root object scope and root lexical scope to reuse them in\n  // our mapped scopes. This assumes that file file being processed is\n  // a CommonJS or ES6 module, which might not be ideal. Potentially\n  // should add some logic to try to detect those cases?\n  let globalLexicalScope: ?OriginalScope = null;\n  for (let s = scopes; s.parent; s = s.parent) {\n    // $FlowIgnore - Flow doesn't like casting 'parent'.\n    globalLexicalScope = s;\n  }\n  if (!globalLexicalScope) {\n    throw new Error(\"Assertion failure - there should always be a scope\");\n  }\n\n  // Build a structure similar to the client's linked scope object using\n  // the original AST scopes, but pulling in the generated bindings\n  // linked to each scope.\n  const result = originalScopes\n    .slice(0, -2)\n    .reverse()\n    .reduce((acc, orig, i): OriginalScope => {\n      const {\n        // The 'this' binding data we have is handled independently, so\n        // the binding data is not included here.\n        // eslint-disable-next-line no-unused-vars\n        this: _this,\n        ...variables\n      } = orig.generatedBindings;\n\n      return {\n        parent: acc,\n        actor: `originalActor${i}`,\n        type: orig.type,\n        bindings: {\n          arguments: [],\n          variables\n        },\n        ...(orig.type === \"function\"\n          ? {\n              function: {\n                displayName: orig.displayName\n              }\n            }\n          : null),\n        ...(orig.type === \"block\"\n          ? {\n              block: {\n                displayName: orig.displayName\n              }\n            }\n          : null)\n      };\n    }, globalLexicalScope);\n\n  // The rendering logic in getScope 'this' bindings only runs on the current\n  // selected frame scope, so we pluck out the 'this' binding that was mapped,\n  // and put it in a special location\n  const thisScope = originalScopes.find(scope => scope.bindings.this);\n  if (thisScope) {\n    result.bindings.this = thisScope.generatedBindings.this || null;\n  }\n\n  return result;\n}\n\nfunction hasValidIdent(range: MappedOriginalRange, pos: BindingLocation) {\n  return (\n    range.type === \"match\" ||\n    // For declarations, we allow the range on the identifier to be a\n    // more general \"contains\" to increase the chances of a match.\n    (pos.type !== \"ref\" && range.type === \"contains\")\n  );\n}\n\n// eslint-disable-next-line complexity\nasync function findGeneratedBinding(\n  sourceMaps: any,\n  client: any,\n  source: Source,\n  name: string,\n  originalBinding: BindingData,\n  originalRanges: Array<MappedOriginalRange>,\n  generatedAstBindings: Array<GeneratedBindingLocation>\n): Promise<?{\n  grip: BindingContents,\n  expression: string | null\n}> {\n  // If there are no references to the implicits, then we have no way to\n  // even attempt to map it back to the original since there is no location\n  // data to use. Bail out instead of just showing it as unmapped.\n  if (\n    originalBinding.type === \"implicit\" &&\n    !originalBinding.refs.some(item => item.type === \"ref\")\n  ) {\n    return null;\n  }\n\n  const { refs } = originalBinding;\n\n  let genContent: GeneratedDescriptor | null = null;\n  for (const pos of refs) {\n    const range = findMatchingRange(originalRanges, pos);\n    if (range && hasValidIdent(range, pos)) {\n      if (originalBinding.type === \"import\") {\n        genContent = await findGeneratedBindingForImportBinding(\n          sourceMaps,\n          client,\n          source,\n          pos,\n          name,\n          originalBinding.type,\n          generatedAstBindings\n        );\n      } else {\n        genContent = await findGeneratedBindingForStandardBinding(\n          sourceMaps,\n          client,\n          source,\n          pos,\n          name,\n          originalBinding.type,\n          generatedAstBindings\n        );\n      }\n    }\n\n    if (\n      (pos.type === \"class-decl\" || pos.type === \"class-inner\") &&\n      source.contentType &&\n      source.contentType.match(/\\/typescript/)\n    ) {\n      const declRange = findMatchingRange(originalRanges, pos.declaration);\n      if (declRange && declRange.type !== \"multiple\") {\n        // Resolve to first binding in the range\n        const declContent = await findGeneratedBindingForNormalDeclaration(\n          sourceMaps,\n          client,\n          source,\n          pos,\n          name,\n          originalBinding.type,\n          generatedAstBindings\n        );\n\n        if (declContent) {\n          // Prefer the declaration mapping in this case because TS sometimes\n          // maps class declaration names to \"export.Foo = Foo;\" or to\n          // the decorator logic itself\n          genContent = declContent;\n        }\n      }\n    }\n\n    if (\n      !genContent &&\n      (pos.type === \"import-decl\" || pos.type === \"import-ns-decl\")\n    ) {\n      const declRange = findMatchingRange(originalRanges, pos.declaration);\n\n      // The import declaration should have an original position mapping,\n      // but otherwise we don't really have preferences on the range type\n      // because it can have multiple bindings, but we do want to make sure\n      // that all of the bindings that match the range are part of the same\n      // import declaration.\n      if (declRange && declRange.singleDeclaration) {\n        // match the import declaration location\n        genContent = await findGeneratedBindingForImportDeclaration(\n          sourceMaps,\n          client,\n          source,\n          pos,\n          name,\n          originalBinding.type,\n          generatedAstBindings\n        );\n      }\n    }\n\n    if (genContent) {\n      break;\n    }\n  }\n\n  if (genContent && genContent.desc) {\n    return {\n      grip: genContent.desc,\n      expression: genContent.expression\n    };\n  } else if (genContent) {\n    // If there is no descriptor for 'this', then this is not the top-level\n    // 'this' that the server gave us a binding for, and we can just ignore it.\n    if (name === \"this\") {\n      return null;\n    }\n\n    // If the location is found but the descriptor is not, then it\n    // means that the server scope information didn't match the scope\n    // information from the DevTools parsed scopes.\n    return {\n      grip: {\n        configurable: false,\n        enumerable: true,\n        writable: false,\n        value: {\n          type: \"unscoped\",\n          unscoped: true,\n\n          // HACK: Until support for \"unscoped\" lands in devtools-reps,\n          // this will make these show as (unavailable).\n          missingArguments: true\n        }\n      },\n      expression: null\n    };\n  }\n\n  // If no location mapping is found, then the map is bad, or\n  // the map is okay but it original location is inside\n  // of some scope, but the generated location is outside, leading\n  // us to search for bindings that don't technically exist.\n  return {\n    grip: {\n      configurable: false,\n      enumerable: true,\n      writable: false,\n      value: {\n        type: \"unmapped\",\n        unmapped: true,\n\n        // HACK: Until support for \"unmapped\" lands in devtools-reps,\n        // this will make these show as (unavailable).\n        missingArguments: true\n      }\n    },\n    expression: null\n  };\n}\n\n\n\n// WEBPACK FOOTER //\n// C:/src/github.com/janodvarko/debugger.html/src/utils/pause/mapScopes/index.js","contentType":"text/javascript","loadedState":"loaded"},"http://localhost:8000/assets/build/debugger.js","webpack:///C:/src/github.com/janodvarko/debugger.html/src/utils/pause/mapScopes/index.js","http://10.0.3.111:8080/www/xhr-spy/tests.js","http://10.0.3.111:8080/www/wasm/import.wasm","http://10.0.3.111:8080/www/wasm/","http://10.0.3.111:8080/www/wasm/test.wasm","http://10.0.3.111:8080/www/wasm/index.js",{"id":"server2.conn4.child1/source78","url":"https://mdn.github.io/webassembly-examples/js-api-examples/fail.wasm","sourceMapURL":null,"isBlackBoxed":false,"isPrettyPrinted":false,"isWasm":true,"text":{"binary":"\u0000asm\u0001\u0000\u0000\u0000\u0001…€€€\u0000\u0001`\u0000\u0001\u0003‚€€€\u0000\u0001\u0000\u0006€€€\u0000\u0000\u0007‹€€€\u0000\u0001\u0007fail_me\u0000\u0000\n€€€\u0000\u0001‡€€€\u0000\u0000A\u0001A\u0000m\u000b"},"contentType":"text/wasm","loadedState":"loaded"},"https://mdn.github.io/webassembly-examples/js-api-examples/fail.html","https://mdn.github.io/webassembly-examples/js-api-examples/fail.wasm","http://localhost:3000/static/js/C:/src/www/my-react-app2/src/App.js","http://10.0.3.111:8080/www/xhr-spy/main.js","http://10.0.3.111:8080/www/xhr-spy/","http://localhost:8080/github.com/janodvarko/harviewer/webapp/scripts/preview/harModel.js","webpack:///~/react-dom/lib/ReactMount.js","webpack:///~/react-dom/lib/ReactCompositeComponent.js","webpack:///src/App.js","http://localhost:3000/static/js/bundle.js","wasm:https://lukewagner.github.io/test-wasm-stacks/%20line%2057%20%3E%20WebAssembly.instantiate","https://lukewagner.github.io/test-wasm-stacks/","http://10.0.3.111:8080/www/xhr-spy/index.js"]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement