Repository: source-academy/js-slang
Pull request #494 (2020-04-03 10:33:09)

Fix Scope Highlighting Bug
Fixes the following bug:

![photo6068928255882275468](https://user-images.githubusercontent.com/25262251/78351773-ee06d680-75d9-11ea-9bc6-181742379449.jpg)


After fix:
![Screen Shot 2020-04-03 at 6 34 16 PM](https://user-images.githubusercontent.com/25262251/78351660-c0219200-75d9-11ea-83cf-d690d9a0fb58.png)



coveralls: ## Pull Request Test Coverage Report for [Build 2471](https://coveralls.io/builds/29820478)

* **5** of **5**   **(100.0%)**  changed or added relevant lines in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **89.342%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/29820478/badge)](https://coveralls.io/builds/29820478) |
| :-- | --: |
| Change from base [Build 2458](https://coveralls.io/builds/29810578): |  0.0% |
| Covered Lines: | 4045 |
| Relevant Lines: | 4388 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/src/scope-refactoring.ts b/src/scope-refactoring.ts
index 8c2f805a..ef8cc3bd 100644
--- a/src/scope-refactoring.ts
+++ b/src/scope-refactoring.ts
@@ -231,17 +231,17 @@ export function getScopeHelper(
     .map(child => getChildBlocksWithDefinitions(child, target))
     .reduce((x, y) => [...x, ...y], [])
 
-  const rangeToExclude = childBlocksWithDefinitions.map(b => b.enclosingLoc)
+  const rangesToExclude = childBlocksWithDefinitions.map(b => b.enclosingLoc)
 
-  if (parentRange && rangeToExclude.length === 0) {
+  if (parentRange && rangesToExclude.length === 0) {
     return [parentRange]
   }
 
   const ranges: es.SourceLocation[] = []
-  let prevRange = rangeToExclude.shift()
+  let prevRange = rangesToExclude.shift()
   ranges.push({ start: (parentRange as any).start, end: (prevRange as any).start })
-  rangeToExclude.map(range => {
-    ranges.push({ start: (prevRange as any).end, end: (rangeToExclude.shift() as any).start })
+  rangesToExclude.map(range => {
+    ranges.push({ start: (prevRange as any).end, end: (range as any).start })
     prevRange = range
   })
   ranges.push({ start: (prevRange as any).end, end: (parentRange as any).end })


Test patch:
diff --git a/src/__tests__/__snapshots__/index.ts.snap b/src/__tests__/__snapshots__/index.ts.snap
index d76de914..bcc00d13 100644
--- a/src/__tests__/__snapshots__/index.ts.snap
+++ b/src/__tests__/__snapshots__/index.ts.snap
@@ -669,6 +669,51 @@ Array [
 ]
 `;
 
+exports[`Find scope of a variable declaration with multiple blocks 1`] = `
+Array [
+  Object {
+    "end": Position {
+      "column": 8,
+      "line": 4,
+    },
+    "start": Position {
+      "column": 4,
+      "line": 2,
+    },
+  },
+  Object {
+    "end": Position {
+      "column": 8,
+      "line": 8,
+    },
+    "start": Position {
+      "column": 9,
+      "line": 6,
+    },
+  },
+  Object {
+    "end": Position {
+      "column": 8,
+      "line": 12,
+    },
+    "start": Position {
+      "column": 9,
+      "line": 10,
+    },
+  },
+  Object {
+    "end": Position {
+      "column": 5,
+      "line": 15,
+    },
+    "start": Position {
+      "column": 9,
+      "line": 14,
+    },
+  },
+]
+`;
+
 exports[`Find variable declaration in block statement 1`] = `
 SourceLocation {
   "end": Position {
diff --git a/src/__tests__/index.ts b/src/__tests__/index.ts
index c9da5c84..044c66cf 100644
--- a/src/__tests__/index.ts
+++ b/src/__tests__/index.ts
@@ -829,3 +829,40 @@ test('Find scope of a variable declaration with more nesting', () => {
   })
   expect(actual).toMatchSnapshot()
 })
+
+test('Find scope of a variable declaration with multiple blocks', () => {
+  const context = createTestContext({ chapter: 4 })
+  const code = `const x = 1;
+    {
+        const x = 2;
+        {
+            const x = 3;
+        }
+        x ;
+        {
+            const x = 4;
+        }
+        x;
+        {
+            const x = 5;
+        }
+    }
+    x;`
+  const expected = [
+    new SourceLocationTestResult(2, 4, 4, 8),
+    new SourceLocationTestResult(6, 9, 8, 8),
+    new SourceLocationTestResult(10, 9, 12, 8),
+    new SourceLocationTestResult(14, 9, 15, 5)
+  ]
+  const actual = getScope(code, context, { line: 3, column: 15 })
+  expected.forEach((expectedRange, index) => {
+    const actualRange = new SourceLocationTestResult(
+      actual[index].start.line,
+      actual[index].start.column,
+      actual[index].end.line,
+      actual[index].end.column
+    )
+    expectResultsToMatch(actualRange, expectedRange)
+  })
+  expect(actual).toMatchSnapshot()
+})