mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This patch changes the syntax map data structure it uses to be offset based rather than line/col based in order to avoid calling getLineAndColumn for the start and end offset of every token. This removes the 30% of time spent in getLineAndColumn for this request in large files (rdar://problem/28965123). The logic for returning the affected range and the token ranges to highlight following an edit also made several assumptions that no longer hold. This patch changes it to compare the syntax maps from before and after the edit, find the first mismtaching tokens from the start and end of the syntax maps and return the tokens in that range (adjusted to line boundaries). This fixes syntax highlighting issues with interpolated multi-line strings (rdar://problem/32148117) and block comments. With the above changes the per-keystroke time spent for syntax highlighting (with sematic info disabled) dropped from ~80ms to just under 50ms for a 12KLOC file.
272 lines
9.5 KiB
Swift
272 lines
9.5 KiB
Swift
// RUN: %sourcekitd-test -req=open -print-raw-response %S/Inputs/syntaxmap-multiple-edits.swift == -req=edit -print-raw-response -pos=6:13 -length=1 -replace=" " %S/Inputs/syntaxmap-multiple-edits.swift == -req="edit" -pos=14:1 -length=0 -replace="let y = 2" -print-raw-response %S/Inputs/syntaxmap-multiple-edits.swift == -req="edit" -pos=8:10 -length=7 -replace='Int64 = 3; let z = 2' -print-raw-response %S/Inputs/syntaxmap-multiple-edits.swift == -req="edit" -pos=4:9 -length=2 -replace='50 * 95 - 100' -print-raw-response %S/Inputs/syntaxmap-multiple-edits.swift == -req="edit" -pos=1:1 -length=0 -replace='func firstFunc(x: Int) {}' -print-raw-response %S/Inputs/syntaxmap-multiple-edits.swift | %sed_clean > %t.response
|
|
// RUN: %FileCheck -input-file=%t.response %s
|
|
|
|
// Initial syntax map
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.offset: 0,
|
|
// CHECK-NEXT: key.length: 152,
|
|
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse,
|
|
// CHECK-NEXT: key.syntaxmap: [
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.doccomment,
|
|
// CHECK-NEXT: key.offset: 2,
|
|
// CHECK-NEXT: key.length: 14
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.doccomment,
|
|
// CHECK-NEXT: key.offset: 16,
|
|
// CHECK-NEXT: key.length: 6
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.doccomment.field,
|
|
// CHECK-NEXT: key.offset: 22,
|
|
// CHECK-NEXT: key.length: 4
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.doccomment,
|
|
// CHECK-NEXT: key.offset: 26,
|
|
// CHECK-NEXT: key.length: 19
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 45,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 49,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 53,
|
|
// CHECK-NEXT: key.length: 2
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 57,
|
|
// CHECK-NEXT: key.length: 6
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 64,
|
|
// CHECK-NEXT: key.length: 5
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 74,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 78,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.typeidentifier,
|
|
// CHECK-NEXT: key.offset: 81,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 87,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 91,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 95,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.typeidentifier,
|
|
// CHECK-NEXT: key.offset: 98,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 104,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 109,
|
|
// CHECK-NEXT: key.length: 4
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 114,
|
|
// CHECK-NEXT: key.length: 4
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 127,
|
|
// CHECK-NEXT: key.length: 6
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 134,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 136,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 140,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 142,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: ],
|
|
|
|
// After replacing a space with a space
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.diagnostic_stage: source.diagnostic.stage.swift.parse
|
|
// CHECK-NEXT: key.syntaxmap: [
|
|
// CHECK-NEXT: ],
|
|
|
|
// After adding code at the end of the file
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.offset: 151,
|
|
// CHECK-NEXT: key.length: 10,
|
|
// 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: 151,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 155,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 159,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: ],
|
|
|
|
|
|
// After inserting more than we removed
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.offset: 89,
|
|
// CHECK-NEXT: key.length: 30,
|
|
// 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: 91,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 95,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.typeidentifier,
|
|
// CHECK-NEXT: key.offset: 98,
|
|
// CHECK-NEXT: key.length: 5
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 106,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.keyword,
|
|
// CHECK-NEXT: key.offset: 109,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 113,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 117,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: ],
|
|
|
|
// After inserting less than we removed
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.offset: 45,
|
|
// CHECK-NEXT: key.length: 22,
|
|
// 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: 45,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 49,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 53,
|
|
// CHECK-NEXT: key.length: 2
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 58,
|
|
// CHECK-NEXT: key.length: 2
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.number,
|
|
// CHECK-NEXT: key.offset: 63,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: ],
|
|
|
|
// After adding code at the start of the file
|
|
|
|
// CHECK: {{^}}{
|
|
// CHECK-NEXT: key.offset: 0,
|
|
// CHECK-NEXT: key.length: 27,
|
|
// 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: 4
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 5,
|
|
// CHECK-NEXT: key.length: 9
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.identifier,
|
|
// CHECK-NEXT: key.offset: 15,
|
|
// CHECK-NEXT: key.length: 1
|
|
// CHECK-NEXT: },
|
|
// CHECK-NEXT: {
|
|
// CHECK-NEXT: key.kind: source.lang.swift.syntaxtype.typeidentifier,
|
|
// CHECK-NEXT: key.offset: 18,
|
|
// CHECK-NEXT: key.length: 3
|
|
// CHECK-NEXT: }
|
|
// CHECK-NEXT: ],
|
|
|