[SyntaxColor] Improve highligting of multiline strings

Multiline strings (and multiline tokens in general) were not well supported by the existing highlighting logic. Edits
on one line can make tokens appear/disappear on previous and later lines, which broke assumptions in the existing
logic, and left odd ranges of source unhighlighted or out of date. This patch accounts for these changes, and also
changes unterminated  multiline (and regular strings) to still be highlighted as strings, so the rest of the
file doesn't look like plain text.

Resolves rdar://problem/32148117.
This commit is contained in:
Nathan Hawes
2017-05-22 16:53:32 -07:00
parent 664948eb3c
commit 56fb4a5d9f
9 changed files with 436 additions and 82 deletions

View File

@@ -0,0 +1,154 @@
// RUN: %sourcekitd-test -req=open -print-raw-response %S/Inputs/syntaxmap-edit-multiline-string.swift == -req=edit -print-raw-response %S/Inputs/syntaxmap-edit-multiline-string.swift -pos=8:1 -replace='"""' -length=3 == -req=edit -print-raw-response %S/Inputs/syntaxmap-edit-multiline-string.swift -pos=6:2 -replace=')' -length=1 == -req=edit -print-raw-response %S/Inputs/syntaxmap-edit-multiline-string.swift -pos=2:10 -replace=' ' -length=1 | %sed_clean > %t.response
// RUN: %FileCheck -input-file=%t.response %s
// Original file contents
// CHECK: {{^}}{
// CHECK-NEXT: key.offset: 0,
// CHECK-NEXT: key.length: 84,
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse,
// CHECK-NEXT: key.syntaxmap: [
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
// CHECK-NEXT: key.offset: 0,
// CHECK-NEXT: key.length: 3
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 4,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 8,
// CHECK-NEXT: key.length: 7
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
// CHECK-NEXT: key.offset: 16,
// CHECK-NEXT: key.length: 3
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 20,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 24,
// CHECK-NEXT: key.length: 60
// CHECK-NEXT: }
// CHECK-NEXT: ],
// After terminating the multiline string
// CHECK: {{^}}{
// CHECK-NEXT: key.offset: 24,
// CHECK-NEXT: key.length: 60,
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse,
// CHECK-NEXT: key.syntaxmap: [
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 24,
// CHECK-NEXT: key.length: 5
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string_interpolation_anchor,
// CHECK-NEXT: key.offset: 30,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 32,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string_interpolation_anchor,
// CHECK-NEXT: key.offset: 34,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 35,
// CHECK-NEXT: key.length: 6
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
// CHECK-NEXT: key.offset: 43,
// CHECK-NEXT: key.length: 4
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 48,
// CHECK-NEXT: key.length: 3
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.typeidentifier,
// CHECK-NEXT: key.offset: 58,
// CHECK-NEXT: key.length: 6
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
// CHECK-NEXT: key.offset: 69,
// CHECK-NEXT: key.length: 6
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 76,
// CHECK-NEXT: key.length: 5
// CHECK-NEXT: }
// CHECK-NEXT: ],
// After adding a character after the interpolation
// CHECK: {{^}}{
// CHECK-NEXT: key.offset: 34,
// CHECK-NEXT: key.length: 9,
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse,
// CHECK-NEXT: key.syntaxmap: [
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string_interpolation_anchor,
// CHECK-NEXT: key.offset: 34,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 35,
// CHECK-NEXT: key.length: 6
// CHECK-NEXT: }
// CHECK-NEXT: ],
// After replacing the middle opening quote with a space
// CHECK: {{^}}{
// CHECK-NEXT: key.offset: 16,
// CHECK-NEXT: key.length: 68,
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse,
// CHECK-NEXT: key.syntaxmap: [
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
// CHECK-NEXT: key.offset: 16,
// CHECK-NEXT: key.length: 3
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 20,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 24,
// CHECK-NEXT: key.length: 3
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
// CHECK-NEXT: key.offset: 32,
// CHECK-NEXT: key.length: 1
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.string,
// CHECK-NEXT: key.offset: 38,
// CHECK-NEXT: key.length: 46
// CHECK-NEXT: }
// CHECK-NEXT: ],