diff --git a/extensions/csharp/syntaxes/csharp.tmLanguage.json b/extensions/csharp/syntaxes/csharp.tmLanguage.json index 397c2712e03b..17abddbfec02 100644 --- a/extensions/csharp/syntaxes/csharp.tmLanguage.json +++ b/extensions/csharp/syntaxes/csharp.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/dotnet/csharp-tmLanguage/commit/7689494edad006eafb9025aa6d72f8a634011a00", + "version": "https://github.com/dotnet/csharp-tmLanguage/commit/b68631155b9ba9886fb3ef8f9a94e4c731b41f3d", "name": "C#", "scopeName": "source.cs", "patterns": [ @@ -346,7 +346,7 @@ ] }, "extern-alias-directive": { - "begin": "\\s*(extern)\\b\\s*(alias)\\b\\s*([_[:alpha:]][_[:alnum:]]*)", + "begin": "\\s*(extern)\\b\\s*(alias)\\b\\s*(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "1": { "name": "keyword.other.extern.cs" @@ -380,7 +380,7 @@ ] }, { - "begin": "\\b(using)\\s+(?=([_[:alpha:]][_[:alnum:]]*)\\s*=)", + "begin": "\\b(using)\\s+(?=(@?[_[:alpha:]][_[:alnum:]]*)\\s*=)", "beginCaptures": { "1": { "name": "keyword.other.using.cs" @@ -416,7 +416,7 @@ }, { "name": "entity.name.type.namespace.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#operator-assignment" @@ -492,7 +492,7 @@ ] }, "attribute-named-argument": { - "begin": "([_[:alpha:]][_[:alnum:]]*)\\s*(?==)", + "begin": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(?==)", "beginCaptures": { "1": { "name": "entity.name.variable.property.cs" @@ -522,7 +522,7 @@ }, { "name": "entity.name.type.namespace.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-accessor" @@ -563,7 +563,7 @@ "end": "(?<=\\})", "patterns": [ { - "begin": "(?x)\n\\b(class)\\b\\s+\n([_[:alpha:]][_[:alnum:]]*)\\s*", + "begin": "(?x)\n\\b(class)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)\\s*", "beginCaptures": { "1": { "name": "keyword.other.class.cs" @@ -616,7 +616,7 @@ ] }, "delegate-declaration": { - "begin": "(?x)\n(?:\\b(delegate)\\b)\\s+\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", + "begin": "(?x)\n(?:\\b(delegate)\\b)\\s+\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", "beginCaptures": { "1": { "name": "keyword.other.delegate.cs" @@ -664,7 +664,7 @@ "include": "#comment" }, { - "match": "(enum)\\s+([_[:alpha:]][_[:alnum:]]*)", + "match": "(enum)\\s+(@?[_[:alpha:]][_[:alnum:]]*)", "captures": { "1": { "name": "keyword.other.enum.cs" @@ -717,7 +717,7 @@ "include": "#punctuation-comma" }, { - "begin": "[_[:alpha:]][_[:alnum:]]*", + "begin": "@?[_[:alpha:]][_[:alnum:]]*", "beginCaptures": { "0": { "name": "entity.name.variable.enum-member.cs" @@ -748,7 +748,7 @@ "end": "(?<=\\})", "patterns": [ { - "begin": "(?x)\n(interface)\\b\\s+\n([_[:alpha:]][_[:alnum:]]*)", + "begin": "(?x)\n(interface)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "1": { "name": "keyword.other.interface.cs" @@ -805,7 +805,7 @@ "end": "(?<=\\})", "patterns": [ { - "begin": "(?x)\n(struct)\\b\\s+\n([_[:alpha:]][_[:alnum:]]*)", + "begin": "(?x)\n(struct)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)", "beginCaptures": { "1": { "name": "keyword.other.struct.cs" @@ -880,7 +880,7 @@ } }, { - "match": "\\b([_[:alpha:]][_[:alnum:]]*)\\b", + "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\b", "captures": { "1": { "name": "entity.name.type.type-parameter.cs" @@ -919,7 +919,7 @@ ] }, "generic-constraints": { - "begin": "(where)\\s+([_[:alpha:]][_[:alnum:]]*)\\s*(:)", + "begin": "(where)\\s+(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)", "beginCaptures": { "1": { "name": "keyword.other.where.cs" @@ -967,7 +967,7 @@ ] }, "field-declaration": { - "begin": "(?x)\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s* # first field name\n(?!=>|==)(?=,|;|=|$)", + "begin": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s* # first field name\n(?!=>|==)(?=,|;|=|$)", "beginCaptures": { "1": { "patterns": [ @@ -984,7 +984,7 @@ "patterns": [ { "name": "entity.name.variable.field.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" @@ -1001,7 +1001,7 @@ ] }, "property-declaration": { - "begin": "(?x)\n(?!.*\\b(?:class|interface|struct|enum|event)\\b)\\s*\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?\\g)\\s*\n(?=\\{|=>|$)", + "begin": "(?x)\n(?!.*\\b(?:class|interface|struct|enum|event)\\b)\\s*\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?\\g)\\s*\n(?=\\{|=>|$)", "beginCaptures": { "1": { "patterns": [ @@ -1044,7 +1044,7 @@ ] }, "indexer-declaration": { - "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?this)\\s*\n(?=\\[)", + "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?this)\\s*\n(?=\\[)", "beginCaptures": { "1": { "patterns": [ @@ -1087,7 +1087,7 @@ ] }, "event-declaration": { - "begin": "(?x)\n\\b(event)\\b\\s*\n(?\n (?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?\\g(?:\\s*,\\s*\\g)*)\\s*\n(?=\\{|;|$)", + "begin": "(?x)\n\\b(event)\\b\\s*\n(?\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(?\\g(?:\\s*,\\s*\\g)*)\\s*\n(?=\\{|;|$)", "beginCaptures": { "1": { "name": "keyword.other.event.cs" @@ -1113,7 +1113,7 @@ "patterns": [ { "name": "entity.name.variable.event.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" @@ -1217,7 +1217,7 @@ ] }, "method-declaration": { - "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", + "begin": "(?x)\n(?\n (?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\\s+\n)\n(?\\g\\s*\\.\\s*)?\n(\\g)\\s*\n(<([^<>]+)>)?\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ @@ -1267,11 +1267,11 @@ ] }, "constructor-declaration": { - "begin": "(?=[_[:alpha:]][_[:alnum:]]*\\s*\\()", + "begin": "(?=@?[_[:alpha:]][_[:alnum:]]*\\s*\\()", "end": "(?<=\\})|(?=;)", "patterns": [ { - "match": "\\b([_[:alpha:]][_[:alnum:]]*)\\b", + "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\b", "captures": { "1": { "name": "entity.name.function.cs" @@ -1327,7 +1327,7 @@ ] }, "destructor-declaration": { - "begin": "(~)([_[:alpha:]][_[:alnum:]]*)\\s*(?=\\()", + "begin": "(~)(@?[_[:alpha:]][_[:alnum:]]*)\\s*(?=\\()", "beginCaptures": { "1": { "name": "punctuation.tilde.cs" @@ -1353,7 +1353,7 @@ ] }, "operator-declaration": { - "begin": "(?x)\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?(?:\\b(?:operator)))\\s*\n(?(?:\\+|-|\\*|/|%|&|\\||\\^|\\<\\<|\\>\\>|==|!=|\\>|\\<|\\>=|\\<=|!|~|\\+\\+|--|true|false))\\s*\n(?=\\()", + "begin": "(?x)\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?(?:\\b(?:operator)))\\s*\n(?(?:\\+|-|\\*|/|%|&|\\||\\^|\\<\\<|\\>\\>|==|!=|\\>|\\<|\\>=|\\<=|!|~|\\+\\+|--|true|false))\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ @@ -1386,7 +1386,7 @@ ] }, "conversion-operator-declaration": { - "begin": "(?x)\n(?(?:\\b(?:explicit|implicit)))\\s*\n(?(?:\\b(?:operator)))\\s*\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\()", + "begin": "(?x)\n(?(?:\\b(?:explicit|implicit)))\\s*\n(?(?:\\b(?:operator)))\\s*\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\()", "beginCaptures": { "1": { "patterns": [ @@ -1521,7 +1521,7 @@ }, { "name": "entity.name.label.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" } ] }, @@ -1865,7 +1865,7 @@ }, "patterns": [ { - "match": "(?x)\n(?:\n (\\bvar\\b)|\n (?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\s+\n\\b(in)\\b", + "match": "(?x)\n(?:\n (\\bvar\\b)|\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\s+\n\\b(in)\\b", "captures": { "1": { "name": "keyword.other.var.cs" @@ -1984,7 +1984,7 @@ }, "patterns": [ { - "match": "(?x)\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?:\\b(\\g)\\b)?", + "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?:(\\g)\\b)?", "captures": { "1": { "patterns": [ @@ -2126,7 +2126,7 @@ ] }, "labeled-statement": { - "match": "([_[:alpha:]][_[:alnum:]]*)\\s*(:)", + "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)", "captures": { "1": { "name": "entity.name.label.cs" @@ -2150,7 +2150,7 @@ ] }, "local-variable-declaration": { - "begin": "(?x)\n(?:\n (?:(\\bref)\\s+)?(\\bvar\\b)| # ref local\n (?\n (?:\n (?:ref\\s+)? # ref local\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\s*\n(?=,|;|=|\\))", + "begin": "(?x)\n(?:\n (?:(\\bref)\\s+)?(\\bvar\\b)| # ref local\n (?\n (?:\n (?:ref\\s+)? # ref local\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\s*\n(?=,|;|=|\\))", "beginCaptures": { "1": { "name": "storage.modifier.cs" @@ -2173,7 +2173,7 @@ "patterns": [ { "name": "entity.name.variable.local.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" @@ -2187,7 +2187,7 @@ ] }, "local-constant-declaration": { - "begin": "(?x)\n(?\\b(?:const)\\b)\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s*\n(?=,|;|=)", + "begin": "(?x)\n(?\\b(?:const)\\b)\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)\\s*\n(?=,|;|=)", "beginCaptures": { "1": { "name": "storage.modifier.cs" @@ -2207,7 +2207,7 @@ "patterns": [ { "name": "entity.name.variable.local.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, { "include": "#punctuation-comma" @@ -2283,7 +2283,7 @@ "include": "#punctuation-comma" }, { - "match": "(?x) # e.g. x\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", + "match": "(?x) # e.g. x\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "entity.name.variable.tuple-element.cs" @@ -2319,7 +2319,7 @@ "include": "#punctuation-comma" }, { - "match": "(?x) # e.g. x\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", + "match": "(?x) # e.g. x\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "variable.other.readwrite.cs" @@ -2329,7 +2329,7 @@ ] }, "declaration-expression-local": { - "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n\\b(\\g)\\b\\s*\n(?=[,)\\]])", + "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\b\\s*\n(?=[,)\\]])", "captures": { "1": { "name": "keyword.other.var.cs" @@ -2347,7 +2347,7 @@ } }, "declaration-expression-tuple": { - "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n\\b(\\g)\\b\\s*\n(?=[,)])", + "match": "(?x) # e.g. int x OR var x\n(?:\n \\b(var)\\b|\n (?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n )\n)\\s+\n(\\g)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "keyword.other.var.cs" @@ -2685,7 +2685,7 @@ ] }, "tuple-literal-element": { - "begin": "(?x)\n(?:([_[:alpha:]][_[:alnum:]]*)\\s*(:)\\s*)?\n(?![,)])", + "begin": "(?x)\n(?:(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)\\s*)?\n(?![,)])", "beginCaptures": { "0": { "name": "entity.name.variable.tuple-element.cs" @@ -2819,10 +2819,10 @@ }, "identifier": { "name": "variable.other.readwrite.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" }, "cast-expression": { - "match": "(?x)\n(\\()\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(\\))(?=\\s*[_[:alnum:]\\(])", + "match": "(?x)\n(\\()\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(\\))(?=\\s*@?[_[:alnum:]\\(])", "captures": { "1": { "name": "punctuation.parenthesis.open.cs" @@ -2840,7 +2840,7 @@ } }, "as-expression": { - "match": "(?x)\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?", + "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?", "captures": { "1": { "name": "keyword.other.as.cs" @@ -2855,7 +2855,7 @@ } }, "is-expression": { - "match": "(?x)\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?", + "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?", "captures": { "1": { "name": "keyword.other.is.cs" @@ -2881,7 +2881,7 @@ } }, "invocation-expression": { - "begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n([_[:alpha:]][_[:alnum:]]*)\\s* # method name\n(?\\s*<([^<>]|\\g)+>\\s*)?\\s* # type arguments\n(?=\\() # open paren of argument list", + "begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n(@?[_[:alpha:]][_[:alnum:]]*)\\s* # method name\n(?\\s*<([^<>]|\\g)+>\\s*)?\\s* # type arguments\n(?=\\() # open paren of argument list", "beginCaptures": { "1": { "name": "keyword.operator.null-conditional.cs" @@ -2908,7 +2908,7 @@ ] }, "element-access-expression": { - "begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n(?:([_[:alpha:]][_[:alnum:]]*)\\s*)? # property name\n(?:(\\?)\\s*)? # null-conditional operator?\n(?=\\[) # open bracket of argument list", + "begin": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(?:(\\.)\\s*)? # preceding dot?\n(?:(@?[_[:alpha:]][_[:alnum:]]*)\\s*)? # property name\n(?:(\\?)\\s*)? # null-conditional operator?\n(?=\\[) # open bracket of argument list", "beginCaptures": { "1": { "name": "keyword.operator.null-conditional.cs" @@ -2933,7 +2933,7 @@ "member-access-expression": { "patterns": [ { - "match": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(\\.)\\s* # preceding dot\n([_[:alpha:]][_[:alnum:]]*)\\s* # property name\n(?![_[:alnum:]]|\\(|(\\?)?\\[|<) # next character is not alpha-numeric, nor a (, [, or <. Also, test for ?[", + "match": "(?x)\n(?:(\\?)\\s*)? # preceding null-conditional operator?\n(\\.)\\s* # preceding dot\n(@?[_[:alpha:]][_[:alnum:]]*)\\s* # property name\n(?![_[:alnum:]]|\\(|(\\?)?\\[|<) # next character is not alpha-numeric, nor a (, [, or <. Also, test for ?[", "captures": { "1": { "name": "keyword.operator.null-conditional.cs" @@ -2947,7 +2947,7 @@ } }, { - "match": "(?x)\n(\\.)?\\s*\n([_[:alpha:]][_[:alnum:]]*)\n(?\\s*<([^<>]|\\g)+>\\s*)\n(?=\n (\\s*\\?)?\n \\s*\\.\\s*[_[:alpha:]][_[:alnum:]]*\n)", + "match": "(?x)\n(\\.)?\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\n(?\\s*<([^<>]|\\g)+>\\s*)\n(?=\n (\\s*\\?)?\n \\s*\\.\\s*@?[_[:alpha:]][_[:alnum:]]*\n)", "captures": { "1": { "name": "punctuation.accessor.cs" @@ -2965,7 +2965,7 @@ } }, { - "match": "(?x)\n([_[:alpha:]][_[:alnum:]]*)\n(?=\n (\\s*\\?)?\n \\s*\\.\\s*[_[:alpha:]][_[:alnum:]]*\n)", + "match": "(?x)\n(@?[_[:alpha:]][_[:alnum:]]*)\n(?=\n (\\s*\\?)?\n \\s*\\.\\s*@?[_[:alpha:]][_[:alnum:]]*\n)", "captures": { "1": { "name": "variable.other.object.cs" @@ -2985,7 +2985,7 @@ ] }, "object-creation-expression-with-parameters": { - "begin": "(?x)\n(new)\\s+\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\()", + "begin": "(?x)\n(new)\\s+\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\()", "beginCaptures": { "1": { "name": "keyword.other.new.cs" @@ -3006,7 +3006,7 @@ ] }, "object-creation-expression-with-no-parameters": { - "match": "(?x)\n(new)\\s+\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\{|$)", + "match": "(?x)\n(new)\\s+\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s*\n(?=\\{|$)", "captures": { "1": { "name": "keyword.other.new.cs" @@ -3021,7 +3021,7 @@ } }, "array-creation-expression": { - "begin": "(?x)\n\\b(new)\\b\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\\s*\n(?=\\[)", + "begin": "(?x)\n\\b(new)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\\s*\n(?=\\[)", "beginCaptures": { "1": { "name": "keyword.other.new.cs" @@ -3124,7 +3124,7 @@ ] }, "parameter": { - "match": "(?x)\n(?:(?:\\b(ref|params|out|this)\\b)\\s+)?\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)", + "match": "(?x)\n(?:(?:\\b(ref|params|out|in|this)\\b)\\s+)?\n(?\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g)", "captures": { "1": { "name": "storage.modifier.cs" @@ -3192,7 +3192,7 @@ ] }, "named-argument": { - "begin": "([_[:alpha:]][_[:alnum:]]*)\\s*(:)", + "begin": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(:)", "beginCaptures": { "1": { "name": "entity.name.variable.parameter.cs" @@ -3212,7 +3212,7 @@ "patterns": [ { "name": "storage.modifier.cs", - "match": "\\b(ref|out)\\b" + "match": "\\b(ref|out|in)\\b" }, { "include": "#declaration-expression-local" @@ -3223,7 +3223,7 @@ ] }, "query-expression": { - "begin": "(?x)\n\\b(from)\\b\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n\\b(\\g)\\b\\s*\n\\b(in)\\b\\s*", + "begin": "(?x)\n\\b(from)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n\\s+(\\g)\\b\\s*\n\\b(in)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.query.from.cs" @@ -3275,7 +3275,7 @@ ] }, "let-clause": { - "begin": "(?x)\n\\b(let)\\b\\s*\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(=)\\s*", + "begin": "(?x)\n\\b(let)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(=)\\s*", "beginCaptures": { "1": { "name": "keyword.query.let.cs" @@ -3315,7 +3315,7 @@ ] }, "join-clause": { - "begin": "(?x)\n\\b(join)\\b\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n\\b(\\g)\\b\\s*\n\\b(in)\\b\\s*", + "begin": "(?x)\n\\b(join)\\b\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n\\s+(\\g)\\b\\s*\n\\b(in)\\b\\s*", "beginCaptures": { "1": { "name": "keyword.query.join.cs" @@ -3370,7 +3370,7 @@ } }, "join-into": { - "match": "(?x)\n\\b(into)\\b\\s*\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*", + "match": "(?x)\n\\b(into)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*", "captures": { "1": { "name": "keyword.query.into.cs" @@ -3463,7 +3463,7 @@ } }, "group-into": { - "match": "(?x)\n\\b(into)\\b\\s*\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*", + "match": "(?x)\n\\b(into)\\b\\s*\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*", "captures": { "1": { "name": "keyword.query.into.cs" @@ -3476,7 +3476,7 @@ "anonymous-method-expression": { "patterns": [ { - "begin": "(?x)\n(?:\\b(async)\\b\\s*)?\n\\b([_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(=>)", + "begin": "(?x)\n(?:\\b(async)\\b\\s*)?\n(@?[_[:alpha:]][_[:alnum:]]*)\\b\\s*\n(=>)", "beginCaptures": { "1": { "name": "storage.modifier.cs" @@ -3585,7 +3585,7 @@ ] }, "lambda-parameter": { - "match": "(?x)\n(ref|out)?\\s*\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n\\b(\\g)\\b\\s*\n(?=[,)])", + "match": "(?x)\n(?:\\b(ref|out|in)\\b)?\\s*\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)?\n(\\g)\\b\\s*\n(?=[,)])", "captures": { "1": { "name": "storage.modifier.cs" @@ -3658,7 +3658,7 @@ ] }, "tuple-element": { - "match": "(?x)\n(?\n (?:\n (?:\n (?:(?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\n(?:\\b(?\\g)\\b)?", + "match": "(?x)\n(?\n (?:\n (?:\n (?:(?@?[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (? # identifier + type arguments (if any)\n \\g\\s*\n (?\\s*<(?:[^<>]|\\g)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g)* | # Are there any more names being dotted into?\n (?\\s*\\((?:[^\\(\\)]|\\g)+\\))\n )\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\n(?:(?\\g)\\b)?", "captures": { "1": { "patterns": [ @@ -3683,7 +3683,7 @@ "type-name": { "patterns": [ { - "match": "([_[:alpha:]][_[:alnum:]]*)\\s*(\\:\\:)", + "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(\\:\\:)", "captures": { "1": { "name": "entity.name.type.alias.cs" @@ -3694,7 +3694,7 @@ } }, { - "match": "([_[:alpha:]][_[:alnum:]]*)\\s*(\\.)", + "match": "(@?[_[:alpha:]][_[:alnum:]]*)\\s*(\\.)", "captures": { "1": { "name": "storage.type.cs" @@ -3705,7 +3705,7 @@ } }, { - "match": "(\\.)\\s*([_[:alpha:]][_[:alnum:]]*)", + "match": "(\\.)\\s*(@?[_[:alpha:]][_[:alnum:]]*)", "captures": { "1": { "name": "punctuation.accessor.cs" @@ -3717,7 +3717,7 @@ }, { "name": "storage.type.cs", - "match": "[_[:alpha:]][_[:alnum:]]*" + "match": "@?[_[:alpha:]][_[:alnum:]]*" } ] }, diff --git a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json index eb16f2829ad5..3fc11fdde788 100644 --- a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json +++ b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/ionide/ionide-fsgrammar/commit/9aa4b1055e3173225bc0d4b4e48542c2450beb99", + "version": "https://github.com/ionide/ionide-fsgrammar/commit/e15bff40cf4bc42c82bcbdb2a836e4b944b3ef3e", "name": "fsharp", "scopeName": "source.fsharp", "patterns": [ @@ -387,7 +387,7 @@ }, { "name": "variable.parameter.fsharp", - "match": "[[:alpha:]']\\w*" + "match": "[[:alpha:]'_]\\w*" } ] }, @@ -414,7 +414,7 @@ "patterns": [ { "name": "record.fsharp", - "match": "(type)[\\s]+(private|internal|public)?[\\s]*([[:alpha:]0-9'<>^:,._ ]+)[\\s]*(\\([[:alpha:]0-9'<>^:,._ ]+\\))?[\\s]*((with)|(as [[:alpha:]0-9']+)|(=)|(\\(\\)))", + "match": "(type)[\\s]+(private|internal|public)?[\\s]*([[:alpha:]0-9'<>^:,._]+)[\\s]*(\\([[:alpha:]0-9'<>^:,._ ]+\\))?[\\s]*((with)|(as [[:alpha:]0-9']+)|(=)|(\\(\\)))", "captures": { "1": { "name": "keyword.other.fsharp" diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index fa4961af3e5b..1ed150fa0ac2 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/ee1eb6f2d995b662dc2759a2636ae64aa952c0ba", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/bccefcd3facfca34c7821801692472ac1fce61d6", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -445,6 +445,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#object-binding-pattern" }, @@ -652,6 +655,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#parameter-object-binding-pattern" }, @@ -1688,7 +1694,7 @@ "name": "keyword.control.import.js" } }, - "end": "(?=;|$|^)", + "end": "(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.js", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -2831,6 +2837,40 @@ } } }, + { + "match": "(?)" - }, { "include": "#type" }, @@ -3504,10 +3540,13 @@ "include": "#typeof-operator" }, { - "begin": "([&|])(?=\\s*\\{)", + "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.js" + }, + "2": { + "name": "keyword.operator.assignment.js" } }, "end": "(?<=\\})", @@ -3518,10 +3557,13 @@ ] }, { - "begin": "[&|]", + "begin": "([&|])|(=(?!>))", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.js" + }, + "2": { + "name": "keyword.operator.assignment.js" } }, "end": "(?=\\S)" @@ -3653,7 +3695,7 @@ "patterns": [ { "name": "string.template.js", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js" @@ -3662,7 +3704,7 @@ "end": "(?=`)", "patterns": [ { - "include": "#type-parameters" + "include": "#type-arguments" } ] }, @@ -4541,8 +4583,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", + "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "patterns": [ { "include": "#jsx-tag" @@ -4551,7 +4593,7 @@ }, "jsx-tag": { "name": "meta.tag.js", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "end": "(/>)|(?:())", "endCaptures": { "1": { @@ -4578,7 +4620,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>)", + "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js" diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index a06a9e378b67..3f59ddf8dfe3 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/ee1eb6f2d995b662dc2759a2636ae64aa952c0ba", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/bccefcd3facfca34c7821801692472ac1fce61d6", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -445,6 +445,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#object-binding-pattern" }, @@ -652,6 +655,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#parameter-object-binding-pattern" }, @@ -1688,7 +1694,7 @@ "name": "keyword.control.import.js.jsx" } }, - "end": "(?=;|$|^)", + "end": "(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.js.jsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -2831,6 +2837,40 @@ } } }, + { + "match": "(?)" - }, { "include": "#type" }, @@ -3504,10 +3540,13 @@ "include": "#typeof-operator" }, { - "begin": "([&|])(?=\\s*\\{)", + "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.js.jsx" + }, + "2": { + "name": "keyword.operator.assignment.js.jsx" } }, "end": "(?<=\\})", @@ -3518,10 +3557,13 @@ ] }, { - "begin": "[&|]", + "begin": "([&|])|(=(?!>))", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.js.jsx" + }, + "2": { + "name": "keyword.operator.assignment.js.jsx" } }, "end": "(?=\\S)" @@ -3653,7 +3695,7 @@ "patterns": [ { "name": "string.template.js.jsx", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.js.jsx" @@ -3662,7 +3704,7 @@ "end": "(?=`)", "patterns": [ { - "include": "#type-parameters" + "include": "#type-arguments" } ] }, @@ -4541,8 +4583,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", + "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "patterns": [ { "include": "#jsx-tag" @@ -4551,7 +4593,7 @@ }, "jsx-tag": { "name": "meta.tag.js.jsx", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "end": "(/>)|(?:())", "endCaptures": { "1": { @@ -4578,7 +4620,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>)", + "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.js.jsx" diff --git a/extensions/log/syntaxes/log.tmLanguage.json b/extensions/log/syntaxes/log.tmLanguage.json index 090acf7bc69f..21f8880e6e21 100644 --- a/extensions/log/syntaxes/log.tmLanguage.json +++ b/extensions/log/syntaxes/log.tmLanguage.json @@ -4,12 +4,12 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/emilast/vscode-logfile-highlighter/commit/541479c15f46c5f3e504aafe058dd7b982ad932f", + "version": "https://github.com/emilast/vscode-logfile-highlighter/commit/ec0e98bdfbe3b39da175f9f6983aa7a7109acc93", "name": "Log file", "scopeName": "text.log", "patterns": [ { - "match": "\\b(DEBUG)\\b|(?i)\\b(debug)\\:", + "match": "\\b(DEBUG|Debug|Trace)\\b|(?i)\\b(debug)\\:", "name": "markup.changed log.debug" }, { @@ -17,7 +17,7 @@ "name": "markup.changed log.debug" }, { - "match": "\\b(HINT|INFO|INFORMATION)\\b|(?i)\\b(info|information)\\:", + "match": "\\b(HINT|INFO|INFORMATION|Info|NOTICE)\\b|(?i)\\b(info|information)\\:", "name": "markup.inserted log.info" }, { @@ -25,7 +25,7 @@ "name": "markup.inserted log.info" }, { - "match": "\\b(WARNING|WARN)\\b|(?i)\\b(warning)\\:", + "match": "\\b(WARNING|WARN|Warn)\\b|(?i)\\b(warning)\\:", "name": "markup.deleted log.warning" }, { @@ -33,7 +33,7 @@ "name": "markup.deleted log.warning" }, { - "match": "\\b(ERROR|FAILURE|FAIL)\\b|(?i)\\b(error)\\:", + "match": "\\b(ALERT|CRITICAL|EMERGENCY|ERROR|FAILURE|FAIL|Fatal|Error)\\b|(?i)\\b(error)\\:", "name": "string.regexp, strong log.error" }, { diff --git a/extensions/powershell/language-configuration.json b/extensions/powershell/language-configuration.json index 02e7a9ddec40..f30c0f5f0510 100644 --- a/extensions/powershell/language-configuration.json +++ b/extensions/powershell/language-configuration.json @@ -25,8 +25,8 @@ ], "folding": { "markers": { - "start": "^\\s*#region\\b", - "end": "^\\s*#endregion\\b" + "start": "^\\s*#[rR]egion\\b", + "end": "^\\s*#[eE]nd[rR]egion\\b" } } } \ No newline at end of file diff --git a/extensions/razor/syntaxes/cshtml.tmLanguage.json b/extensions/razor/syntaxes/cshtml.tmLanguage.json index 043e6e3b493e..2995e473ee07 100644 --- a/extensions/razor/syntaxes/cshtml.tmLanguage.json +++ b/extensions/razor/syntaxes/cshtml.tmLanguage.json @@ -120,297 +120,6 @@ "end": "(\\))", "comments": "Covers same line Razor statments with embedded C#" }, - { - "begin": "(^[ \\t]+)?(?=<(?i:script))", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.embedded.leading.html" - } - }, - "end": "(?!\\G)([ \\t]*$\\n?)?", - "endCaptures": { - "1": { - "name": "punctuation.whitespace.embedded.trailing.html" - } - }, - "patterns": [ - { - "begin": "(<)((?i:script))\\b", - "beginCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "entity.name.tag.html" - } - }, - "end": "(/>)|(/)((?i:script))(>)", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - }, - "2": { - "name": "punctuation.definition.tag.begin.html" - }, - "3": { - "name": "entity.name.tag.html" - }, - "4": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.embedded.block.html", - "patterns": [ - { - "begin": "\\G", - "end": "(?=/>|/)", - "patterns": [ - { - "begin": "(>)", - "beginCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "end": "((<))(?=/(?i:script))", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "source.js" - } - }, - "patterns": [ - { - "begin": "\\G", - "end": "(?=|type(?=[\\s=])(?!\\s*=\\s*('|\"|)(text/(javascript|ecmascript|babel)|application/((x-)?javascript|ecmascript|babel)|module)[\\s\"'>])))", - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?=(?i:type\\s*=\\s*('|\"|)(text/(x-handlebars|(x-(handlebars-)?|ng-)?template|html)[\\s\"'>])))", - "end": "((<))(?=/(?i:script))", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.script.html" - }, - "1": { - "name": "punctuation.definition.tag.begin.html" - }, - "2": { - "name": "text.html.cshtml" - } - }, - "patterns": [ - { - "begin": "\\G", - "end": "(>)|(?=/>)", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=)|(?=/>)", - "endCaptures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.tag.metadata.script.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=)|((<)/)((?i:style))(>)", - "endCaptures": { - "0": { - "name": "meta.tag.metadata.style.html" - }, - "1": { - "name": "punctuation.definition.tag.end.html" - }, - "2": { - "name": "punctuation.definition.tag.begin.html" - }, - "3": { - "name": "source.css" - }, - "4": { - "name": "entity.name.tag.html" - }, - "5": { - "name": "punctuation.definition.tag.end.html" - } - }, - "name": "meta.embedded.block.html", - "patterns": [ - { - "begin": "\\G", - "captures": { - "1": { - "name": "punctuation.definition.tag.end.html" - } - }, - "end": "(?=/>)|(>)", - "name": "meta.tag.metadata.style.html", - "patterns": [ - { - "include": "#tag-stuff" - } - ] - }, - { - "begin": "(?!\\G)", - "end": "(?=\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.ts", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -2865,6 +2871,40 @@ } } }, + { + "match": "(?)" - }, { "include": "#type" }, @@ -3538,10 +3574,13 @@ "include": "#typeof-operator" }, { - "begin": "([&|])(?=\\s*\\{)", + "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.ts" + }, + "2": { + "name": "keyword.operator.assignment.ts" } }, "end": "(?<=\\})", @@ -3552,10 +3591,13 @@ ] }, { - "begin": "[&|]", + "begin": "([&|])|(=(?!>))", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.ts" + }, + "2": { + "name": "keyword.operator.assignment.ts" } }, "end": "(?=\\S)" @@ -3687,7 +3729,7 @@ "patterns": [ { "name": "string.template.ts", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.ts" @@ -3696,7 +3738,7 @@ "end": "(?=`)", "patterns": [ { - "include": "#type-parameters" + "include": "#type-arguments" } ] }, diff --git a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json index 7fe3297cc77b..0356ef9535eb 100644 --- a/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json +++ b/extensions/typescript-basics/syntaxes/TypeScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/ee1eb6f2d995b662dc2759a2636ae64aa952c0ba", + "version": "https://github.com/Microsoft/TypeScript-TmLanguage/commit/bccefcd3facfca34c7821801692472ac1fce61d6", "name": "TypeScriptReact", "scopeName": "source.tsx", "patterns": [ @@ -445,6 +445,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#object-binding-pattern" }, @@ -652,6 +655,9 @@ { "include": "#comment" }, + { + "include": "#string" + }, { "include": "#parameter-object-binding-pattern" }, @@ -1688,7 +1694,7 @@ "name": "keyword.control.import.tsx" } }, - "end": "(?=;|$|^)", + "end": "(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", - "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?<=\\))(?!(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*)\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "name": "meta.function-call.tsx", "begin": "(?=(([_$[:alpha:]][_$[:alnum:]]*\\s*\\??\\.\\s*)*|(\\??\\.\\s*)?)([_$[:alpha:]][_$[:alnum:]]*))", - "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", + "end": "(?=\\s*(\\?\\.\\s*)?(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)?\\()", "patterns": [ { "include": "#literal" @@ -2831,6 +2837,40 @@ } } }, + { + "match": "(?)" - }, { "include": "#type" }, @@ -3504,10 +3540,13 @@ "include": "#typeof-operator" }, { - "begin": "([&|])(?=\\s*\\{)", + "begin": "(?:([&|])|(=(?!>)))(?=\\s*\\{)", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.tsx" + }, + "2": { + "name": "keyword.operator.assignment.tsx" } }, "end": "(?<=\\})", @@ -3518,10 +3557,13 @@ ] }, { - "begin": "[&|]", + "begin": "([&|])|(=(?!>))", "beginCaptures": { - "0": { + "1": { "name": "keyword.operator.type.tsx" + }, + "2": { + "name": "keyword.operator.assignment.tsx" } }, "end": "(?=\\S)" @@ -3653,7 +3695,7 @@ "patterns": [ { "name": "string.template.tsx", - "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", + "begin": "([_$[:alpha:]][_$[:alnum:]]*)\\s*(?=(<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)`)", "beginCaptures": { "1": { "name": "entity.name.function.tagged-template.tsx" @@ -3662,7 +3704,7 @@ "end": "(?=`)", "patterns": [ { - "include": "#type-parameters" + "include": "#type-arguments" } ] }, @@ -4541,8 +4583,8 @@ ] }, "jsx-tag-in-expression": { - "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", - "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?x)\n (?:*]|&&|\\|\\||\\?|^return|[^\\._$[:alnum:]]return|^default|[^\\._$[:alnum:]]default|^)\\s*\n (?!<\\s*[_$[:alpha:]][_$[:alnum:]]*((\\s+extends\\s+[^=>])|,)) # look ahead is not type parameter of arrow\n (?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", + "end": "(?!(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "patterns": [ { "include": "#jsx-tag" @@ -4551,7 +4593,7 @@ }, "jsx-tag": { "name": "meta.tag.tsx", - "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>))", + "begin": "(?=(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>))", "end": "(/>)|(?:())", "endCaptures": { "1": { @@ -4578,7 +4620,7 @@ }, "patterns": [ { - "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[]|=>|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>)?\\s+(?!\\?)|\\/?>)", + "begin": "(<)\\s*(?:([_$a-zA-Z][-$\\w.]*)(?\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>|\\<\\s*(((keyof|infer)\\s+)|(([_$[:alpha:]][_$[:alnum:]]*|(\\{([^\\{\\}]|(\\{[^\\{\\}]*\\}))*\\})|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(\\[([^\\[\\]]|(\\[[^\\[\\]]*\\]))*\\])|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\")|(\\`[^\\`]*\\`))(?=\\s*([\\<\\>\\,\\.\\[=]|&(?!&)|\\|(?!\\|)))))([^<>\\(]|(\\(([^\\(\\)]|(\\([^\\(\\)]*\\)))*\\))|(?<==)\\>)*(?!=)\\>)*(?!=)>\\s*)|(\\s+))(?!\\?)|\\/?>)", "beginCaptures": { "1": { "name": "punctuation.definition.tag.begin.tsx" diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index aa156fbf7dee..e720f7409459 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -9,7 +9,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; import { createRandomFile, deleteFile, closeAllEditors, pathEquals } from '../utils'; import { join, basename } from 'path'; -// import * as fs from 'fs'; +import * as fs from 'fs'; suite('workspace-namespace', () => { @@ -75,12 +75,12 @@ suite('workspace-namespace', () => { }); }); - // test('openTextDocument, untitled is dirty', function () { - // return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './newfile.txt'))).then(doc => { - // assert.equal(doc.uri.scheme, 'untitled'); - // assert.ok(doc.isDirty); - // }); - // }); + test('openTextDocument, untitled is dirty', function () { + return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './newfile.txt'))).then(doc => { + assert.equal(doc.uri.scheme, 'untitled'); + assert.ok(doc.isDirty); + }); + }); test('openTextDocument, untitled with host', function () { const uri = vscode.Uri.parse('untitled://localhost/c%24/Users/jrieken/code/samples/foobar.txt'); @@ -113,30 +113,30 @@ suite('workspace-namespace', () => { }); }); - // test('openTextDocument, untitled closes on save', function () { - // const path = join(vscode.workspace.rootPath || '', './newfile.txt'); + test('openTextDocument, untitled closes on save', function () { + const path = join(vscode.workspace.rootPath || '', './newfile.txt'); - // return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + path)).then(doc => { - // assert.equal(doc.uri.scheme, 'untitled'); - // assert.ok(doc.isDirty); + return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + path)).then(doc => { + assert.equal(doc.uri.scheme, 'untitled'); + assert.ok(doc.isDirty); - // let closed: vscode.TextDocument; - // let d0 = vscode.workspace.onDidCloseTextDocument(e => closed = e); + let closed: vscode.TextDocument; + let d0 = vscode.workspace.onDidCloseTextDocument(e => closed = e); - // return vscode.window.showTextDocument(doc).then(() => { - // return doc.save().then(() => { - // assert.ok(closed === doc); - // assert.ok(!doc.isDirty); - // assert.ok(fs.existsSync(path)); + return vscode.window.showTextDocument(doc).then(() => { + return doc.save().then(() => { + assert.ok(closed === doc); + assert.ok(!doc.isDirty); + assert.ok(fs.existsSync(path)); - // d0.dispose(); + d0.dispose(); - // return deleteFile(vscode.Uri.file(join(vscode.workspace.rootPath || '', './newfile.txt'))); - // }); - // }); + return deleteFile(vscode.Uri.file(join(vscode.workspace.rootPath || '', './newfile.txt'))); + }); + }); - // }); - // }); + }); + }); test('openTextDocument, uri scheme/auth/path', function () { @@ -513,14 +513,14 @@ suite('workspace-namespace', () => { // }); // }); - // test('applyEdit', () => { + test('applyEdit', () => { - // return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))).then(doc => { - // let edit = new vscode.WorkspaceEdit(); - // edit.insert(doc.uri, new vscode.Position(0, 0), new Array(1000).join('Hello World')); - // return vscode.workspace.applyEdit(edit); - // }); - // }); + return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled:' + join(vscode.workspace.rootPath || '', './new2.txt'))).then(doc => { + let edit = new vscode.WorkspaceEdit(); + edit.insert(doc.uri, new vscode.Position(0, 0), new Array(1000).join('Hello World')); + return vscode.workspace.applyEdit(edit); + }); + }); // test('applyEdit should fail when editing deleted resource', async () => { diff --git a/package.json b/package.json index 793013753293..9fc99e9a8831 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.24.0", - "distro": "ba59d3ae8e284d5cfe6803e1101e9d86163ab256", + "distro": "fa0e16f4dec2b82b096e9b877572b5a19f294aa7", "author": { "name": "Microsoft Corporation" }, diff --git a/src/vs/base/common/diff/diff.ts b/src/vs/base/common/diff/diff.ts index faa62fad9135..8a567312aac2 100644 --- a/src/vs/base/common/diff/diff.ts +++ b/src/vs/base/common/diff/diff.ts @@ -6,12 +6,10 @@ import { DiffChange } from 'vs/base/common/diff/diffChange'; - function createStringSequence(a: string): ISequence { - return { getLength() { return a.length; }, - getElementHash(pos: number) { return a[pos]; } + getElementAtIndex(pos: number) { return a.charCodeAt(pos); } }; } @@ -22,7 +20,7 @@ export function stringDiff(original: string, modified: string, pretty: boolean): export interface ISequence { getLength(): number; - getElementHash(index: number): string; + getElementAtIndex(index: number): number | string; } export interface IDiffChange { @@ -211,8 +209,6 @@ class DiffChangeHelper { } -const hasOwnProperty = Object.prototype.hasOwnProperty; - /** * An implementation of the difference algorithm described in * "An O(ND) Difference Algorithm and its variations" by Eugene W. Myers @@ -223,8 +219,6 @@ export class LcsDiff { private ModifiedSequence: ISequence; private ContinueProcessingPredicate: IContinueProcessingPredicate; - private m_originalIds: number[]; - private m_modifiedIds: number[]; private m_forwardHistory: number[][]; private m_reverseHistory: number[][]; @@ -235,63 +229,21 @@ export class LcsDiff { this.OriginalSequence = originalSequence; this.ModifiedSequence = newSequence; this.ContinueProcessingPredicate = continueProcessingPredicate; - this.m_originalIds = []; - this.m_modifiedIds = []; this.m_forwardHistory = []; this.m_reverseHistory = []; - - this.ComputeUniqueIdentifiers(); - } - - private ComputeUniqueIdentifiers(): void { - let originalSequenceLength = this.OriginalSequence.getLength(); - let modifiedSequenceLength = this.ModifiedSequence.getLength(); - this.m_originalIds = new Array(originalSequenceLength); - this.m_modifiedIds = new Array(modifiedSequenceLength); - - // Create a new hash table for unique elements from the original - // sequence. - let hashTable: { [key: string]: number; } = {}; - let currentUniqueId = 1; - let i: number; - - // Fill up the hash table for unique elements - for (i = 0; i < originalSequenceLength; i++) { - let originalElementHash = this.OriginalSequence.getElementHash(i); - if (!hasOwnProperty.call(hashTable, originalElementHash)) { - // No entry in the hashtable so this is a new unique element. - // Assign the element a new unique identifier and add it to the - // hash table - this.m_originalIds[i] = currentUniqueId++; - hashTable[originalElementHash] = this.m_originalIds[i]; - } else { - this.m_originalIds[i] = hashTable[originalElementHash]; - } - } - - // Now match up modified elements - for (i = 0; i < modifiedSequenceLength; i++) { - let modifiedElementHash = this.ModifiedSequence.getElementHash(i); - if (!hasOwnProperty.call(hashTable, modifiedElementHash)) { - this.m_modifiedIds[i] = currentUniqueId++; - hashTable[modifiedElementHash] = this.m_modifiedIds[i]; - } else { - this.m_modifiedIds[i] = hashTable[modifiedElementHash]; - } - } } private ElementsAreEqual(originalIndex: number, newIndex: number): boolean { - return this.m_originalIds[originalIndex] === this.m_modifiedIds[newIndex]; + return (this.OriginalSequence.getElementAtIndex(originalIndex) === this.ModifiedSequence.getElementAtIndex(newIndex)); } private OriginalElementsAreEqual(index1: number, index2: number): boolean { - return this.m_originalIds[index1] === this.m_originalIds[index2]; + return (this.OriginalSequence.getElementAtIndex(index1) === this.OriginalSequence.getElementAtIndex(index2)); } private ModifiedElementsAreEqual(index1: number, index2: number): boolean { - return this.m_modifiedIds[index1] === this.m_modifiedIds[index2]; + return (this.ModifiedSequence.getElementAtIndex(index1) === this.ModifiedSequence.getElementAtIndex(index2)); } public ComputeDiff(pretty: boolean): IDiffChange[] { @@ -891,7 +843,8 @@ export class LcsDiff { if (index <= 0 || index >= this.OriginalSequence.getLength() - 1) { return true; } - return /^\s*$/.test(this.OriginalSequence.getElementHash(index)); + const element = this.OriginalSequence.getElementAtIndex(index); + return (typeof element === 'string' && /^\s*$/.test(element)); } private _OriginalRegionIsBoundary(originalStart: number, originalLength: number): boolean { @@ -911,7 +864,8 @@ export class LcsDiff { if (index <= 0 || index >= this.ModifiedSequence.getLength() - 1) { return true; } - return /^\s*$/.test(this.ModifiedSequence.getElementHash(index)); + const element = this.ModifiedSequence.getElementAtIndex(index); + return (typeof element === 'string' && /^\s*$/.test(element)); } private _ModifiedRegionIsBoundary(modifiedStart: number, modifiedLength: number): boolean { diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index 42e7a5447a64..6172b9a30ad3 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -99,6 +99,7 @@ const writeFilePathQueue: { [path: string]: Queue } = Object.create(null); export function writeFile(path: string, data: string, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: NodeBuffer, options?: extfs.IWriteFileOptions): TPromise; +export function writeFile(path: string, data: Uint8Array, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: NodeJS.ReadableStream, options?: extfs.IWriteFileOptions): TPromise; export function writeFile(path: string, data: any, options?: extfs.IWriteFileOptions): TPromise { const queueKey = toQueueKey(path); diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 91e59737d7ca..4f907123ed70 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -915,13 +915,16 @@ export class TreeView extends HeightMap { let doToInsertItemsAlreadyExist: boolean; if (!skipDiff) { - const lcs = new Diff.LcsDiff({ - getLength: () => previousChildrenIds.length, - getElementHash: (i: number) => previousChildrenIds[i] - }, { + const lcs = new Diff.LcsDiff( + { + getLength: () => previousChildrenIds.length, + getElementAtIndex: (i: number) => previousChildrenIds[i] + }, { getLength: () => afterModelItems.length, - getElementHash: (i: number) => afterModelItems[i].id - }, null); + getElementAtIndex: (i: number) => afterModelItems[i].id + }, + null + ); diff = lcs.ComputeDiff(false); diff --git a/src/vs/base/test/common/diff/diff.test.ts b/src/vs/base/test/common/diff/diff.test.ts index 0c07a30b7c93..ab231e6ebe04 100644 --- a/src/vs/base/test/common/diff/diff.test.ts +++ b/src/vs/base/test/common/diff/diff.test.ts @@ -6,20 +6,19 @@ import * as assert from 'assert'; -import { LcsDiff, IDiffChange } from 'vs/base/common/diff/diff'; +import { LcsDiff, IDiffChange, ISequence } from 'vs/base/common/diff/diff'; -class StringDiffSequence { +class StringDiffSequence implements ISequence { constructor(private source: string) { - } getLength() { return this.source.length; } - getElementHash(i: number) { - return this.source.charAt(i); + getElementAtIndex(i: number) { + return this.source.charCodeAt(i); } } diff --git a/src/vs/editor/common/diff/diffComputer.ts b/src/vs/editor/common/diff/diffComputer.ts index 6bccc31a789b..9a8274f23263 100644 --- a/src/vs/editor/common/diff/diffComputer.ts +++ b/src/vs/editor/common/diff/diffComputer.ts @@ -11,87 +11,51 @@ import { ICharChange, ILineChange } from 'vs/editor/common/editorCommon'; const MAXIMUM_RUN_TIME = 5000; // 5 seconds const MINIMUM_MATCHING_CHARACTER_LENGTH = 3; -interface IMarker { - lineNumber: number; - column: number; - offset: number; -} - function computeDiff(originalSequence: ISequence, modifiedSequence: ISequence, continueProcessingPredicate: () => boolean, pretty: boolean): IDiffChange[] { const diffAlgo = new LcsDiff(originalSequence, modifiedSequence, continueProcessingPredicate); return diffAlgo.ComputeDiff(pretty); } -class MarkerSequence implements ISequence { +class LineMarkerSequence implements ISequence { - public buffer: string; - public startMarkers: IMarker[]; - public endMarkers: IMarker[]; + private readonly _lines: string[]; + private readonly _startColumns: number[]; + private readonly _endColumns: number[]; - constructor(buffer: string, startMarkers: IMarker[], endMarkers: IMarker[]) { - this.buffer = buffer; - this.startMarkers = startMarkers; - this.endMarkers = endMarkers; + constructor(lines: string[]) { + let startColumns: number[] = []; + let endColumns: number[] = []; + for (let i = 0, length = lines.length; i < length; i++) { + startColumns[i] = LineMarkerSequence._getFirstNonBlankColumn(lines[i], 1); + endColumns[i] = LineMarkerSequence._getLastNonBlankColumn(lines[i], 1); + } + this._lines = lines; + this._startColumns = startColumns; + this._endColumns = endColumns; } public getLength(): number { - return this.startMarkers.length; + return this._lines.length; } - public getElementHash(i: number): string { - return this.buffer.substring(this.startMarkers[i].offset, this.endMarkers[i].offset); + public getElementAtIndex(i: number): string { + return this._lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1); } public getStartLineNumber(i: number): number { - if (i === this.startMarkers.length) { - // This is the special case where a change happened after the last marker - return this.startMarkers[i - 1].lineNumber + 1; - } - return this.startMarkers[i].lineNumber; + return i + 1; } public getStartColumn(i: number): number { - return this.startMarkers[i].column; + return this._startColumns[i]; } public getEndLineNumber(i: number): number { - return this.endMarkers[i].lineNumber; + return i + 1; } public getEndColumn(i: number): number { - return this.endMarkers[i].column; - } - -} - -class LineMarkerSequence extends MarkerSequence { - - constructor(lines: string[]) { - let buffer = ''; - let startMarkers: IMarker[] = []; - let endMarkers: IMarker[] = []; - - for (let pos = 0, i = 0, length = lines.length; i < length; i++) { - buffer += lines[i]; - const startColumn = LineMarkerSequence._getFirstNonBlankColumn(lines[i], 1); - const endColumn = LineMarkerSequence._getLastNonBlankColumn(lines[i], 1); - - startMarkers.push({ - offset: pos + startColumn - 1, - lineNumber: i + 1, - column: startColumn - }); - - endMarkers.push({ - offset: pos + endColumn - 1, - lineNumber: i + 1, - column: endColumn - }); - - pos += lines[i].length; - } - - super(buffer, startMarkers, endMarkers); + return this._endColumns[i]; } public static _getFirstNonBlankColumn(txt: string, defaultValue: number): number { @@ -110,26 +74,60 @@ class LineMarkerSequence extends MarkerSequence { return r + 2; } - public getCharSequence(startIndex: number, endIndex: number): MarkerSequence { - let startMarkers: IMarker[] = []; - let endMarkers: IMarker[] = []; + public getCharSequence(shouldIgnoreTrimWhitespace: boolean, startIndex: number, endIndex: number): CharSequence { + let charCodes: number[] = []; + let lineNumbers: number[] = []; + let columns: number[] = []; + let len = 0; for (let index = startIndex; index <= endIndex; index++) { - const startMarker = this.startMarkers[index]; - const endMarker = this.endMarkers[index]; - for (let i = startMarker.offset; i < endMarker.offset; i++) { - startMarkers.push({ - offset: i, - lineNumber: startMarker.lineNumber, - column: startMarker.column + (i - startMarker.offset) - }); - endMarkers.push({ - offset: i + 1, - lineNumber: startMarker.lineNumber, - column: startMarker.column + (i - startMarker.offset) + 1 - }); + const lineContent = this._lines[index]; + const startColumn = (shouldIgnoreTrimWhitespace ? this._startColumns[index] : 1); + const endColumn = (shouldIgnoreTrimWhitespace ? this._endColumns[index] : lineContent.length + 1); + for (let col = startColumn; col < endColumn; col++) { + charCodes[len] = lineContent.charCodeAt(col - 1); + lineNumbers[len] = index + 1; + columns[len] = col; + len++; } } - return new MarkerSequence(this.buffer, startMarkers, endMarkers); + return new CharSequence(charCodes, lineNumbers, columns); + } +} + +class CharSequence implements ISequence { + + private readonly _charCodes: number[]; + private readonly _lineNumbers: number[]; + private readonly _columns: number[]; + + constructor(charCodes: number[], lineNumbers: number[], columns: number[]) { + this._charCodes = charCodes; + this._lineNumbers = lineNumbers; + this._columns = columns; + } + + public getLength(): number { + return this._charCodes.length; + } + + public getElementAtIndex(i: number): number { + return this._charCodes[i]; + } + + public getStartLineNumber(i: number): number { + return this._lineNumbers[i]; + } + + public getStartColumn(i: number): number { + return this._columns[i]; + } + + public getEndLineNumber(i: number): number { + return this._lineNumbers[i]; + } + + public getEndColumn(i: number): number { + return this._columns[i] + 1; } } @@ -165,7 +163,7 @@ class CharChange implements ICharChange { this.modifiedEndColumn = modifiedEndColumn; } - public static createFromDiffChange(diffChange: IDiffChange, originalCharSequence: MarkerSequence, modifiedCharSequence: MarkerSequence): CharChange { + public static createFromDiffChange(diffChange: IDiffChange, originalCharSequence: CharSequence, modifiedCharSequence: CharSequence): CharChange { let originalStartLineNumber: number; let originalStartColumn: number; let originalEndLineNumber: number; @@ -257,7 +255,7 @@ class LineChange implements ILineChange { this.charChanges = charChanges; } - public static createFromDiffResult(diffChange: IDiffChange, originalLineSequence: LineMarkerSequence, modifiedLineSequence: LineMarkerSequence, continueProcessingPredicate: () => boolean, shouldPostProcessCharChanges: boolean): LineChange { + public static createFromDiffResult(shouldIgnoreTrimWhitespace: boolean, diffChange: IDiffChange, originalLineSequence: LineMarkerSequence, modifiedLineSequence: LineMarkerSequence, continueProcessingPredicate: () => boolean, shouldPostProcessCharChanges: boolean): LineChange { let originalStartLineNumber: number; let originalEndLineNumber: number; let modifiedStartLineNumber: number; @@ -281,8 +279,8 @@ class LineChange implements ILineChange { } if (diffChange.originalLength !== 0 && diffChange.modifiedLength !== 0 && continueProcessingPredicate()) { - const originalCharSequence = originalLineSequence.getCharSequence(diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1); - const modifiedCharSequence = modifiedLineSequence.getCharSequence(diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1); + const originalCharSequence = originalLineSequence.getCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1); + const modifiedCharSequence = modifiedLineSequence.getCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1); let rawChanges = computeDiff(originalCharSequence, modifiedCharSequence, continueProcessingPredicate, true); @@ -332,7 +330,7 @@ export class DiffComputer { public computeDiff(): ILineChange[] { - if (this.original.getLength() === 1 && this.original.getElementHash(0).length === 0) { + if (this.original.getLength() === 1 && this.original.getElementAtIndex(0).length === 0) { // empty original => fast path return [{ originalStartLineNumber: 1, @@ -352,7 +350,7 @@ export class DiffComputer { }]; } - if (this.modified.getLength() === 1 && this.modified.getElementHash(0).length === 0) { + if (this.modified.getLength() === 1 && this.modified.getElementAtIndex(0).length === 0) { // empty modified => fast path return [{ originalStartLineNumber: 1, @@ -382,7 +380,7 @@ export class DiffComputer { if (this.shouldIgnoreTrimWhitespace) { let lineChanges: LineChange[] = []; for (let i = 0, length = rawChanges.length; i < length; i++) { - lineChanges.push(LineChange.createFromDiffResult(rawChanges[i], this.original, this.modified, this._continueProcessingPredicate.bind(this), this.shouldPostProcessCharChanges)); + lineChanges.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, rawChanges[i], this.original, this.modified, this._continueProcessingPredicate.bind(this), this.shouldPostProcessCharChanges)); } return lineChanges; } @@ -457,7 +455,7 @@ export class DiffComputer { if (nextChange) { // Emit the actual change - result.push(LineChange.createFromDiffResult(nextChange, this.original, this.modified, this._continueProcessingPredicate.bind(this), this.shouldPostProcessCharChanges)); + result.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, nextChange, this.original, this.modified, this._continueProcessingPredicate.bind(this), this.shouldPostProcessCharChanges)); originalLineIndex += nextChange.originalLength; modifiedLineIndex += nextChange.modifiedLength; diff --git a/src/vs/editor/common/modes/languageFeatureRegistry.ts b/src/vs/editor/common/modes/languageFeatureRegistry.ts index 2ffe037a5bad..c5e4e7010d88 100644 --- a/src/vs/editor/common/modes/languageFeatureRegistry.ts +++ b/src/vs/editor/common/modes/languageFeatureRegistry.ts @@ -18,6 +18,16 @@ interface Entry { _time: number; } +function isExclusive(selector: LanguageSelector): boolean { + if (typeof selector === 'string') { + return false; + } else if (Array.isArray(selector)) { + return selector.every(isExclusive); + } else { + return selector.exclusive; + } +} + export default class LanguageFeatureRegistry { private _clock: number = 0; @@ -142,6 +152,16 @@ export default class LanguageFeatureRegistry { for (let entry of this._entries) { entry._score = score(entry.selector, model.uri, model.getLanguageIdentifier().language, shouldSynchronizeModel(model)); + + if (isExclusive(entry.selector) && entry._score > 0) { + // support for one exclusive selector that overwrites + // any other selector + for (let entry of this._entries) { + entry._score = 0; + } + entry._score = 1000; + break; + } } // needs sorting diff --git a/src/vs/editor/common/modes/languageSelector.ts b/src/vs/editor/common/modes/languageSelector.ts index a5bac2ab4fb1..513ca2cc2d60 100644 --- a/src/vs/editor/common/modes/languageSelector.ts +++ b/src/vs/editor/common/modes/languageSelector.ts @@ -16,6 +16,7 @@ export interface LanguageFilter { * This provider is implemented in the UI thread. */ hasAccessToAllModels?: boolean; + exclusive?: boolean; } export type LanguageSelector = string | LanguageFilter | (string | LanguageFilter)[]; @@ -43,8 +44,8 @@ export function score(selector: LanguageSelector, candidateUri: URI, candidateLa } // short-hand notion, desugars to - // 'fooLang' -> [{ language: 'fooLang', scheme: 'file' }, { language: 'fooLang', scheme: 'untitled' }] - // '*' -> { language: '*', scheme: '*' } + // 'fooLang' -> { language: 'fooLang'} + // '*' -> { language: '*' } if (selector === '*') { return 5; } else if (selector === candidateLanguage) { diff --git a/src/vs/editor/test/common/diff/diffComputer.test.ts b/src/vs/editor/test/common/diff/diffComputer.test.ts index db7febae627c..2a7cc783ee3a 100644 --- a/src/vs/editor/test/common/diff/diffComputer.test.ts +++ b/src/vs/editor/test/common/diff/diffComputer.test.ts @@ -679,7 +679,7 @@ suite('Editor Diff - DiffComputer', () => { ' * `yarn [install]` -- Install project NPM dependencies. This is automatically done when you first create the project. You should only need to run this if you add dependencies in `package.json`.', ]; let modified = [ - ' * `yarn` -- Install project NPM dependencies. You should only need to run this if you add dependencies in `package.json`.', + ' * `yarn` -- Install project NPM dependencies. You should only need to run this if you add dependencies in `package.json`.', ]; let expected = [ createLineChange( @@ -692,4 +692,24 @@ suite('Editor Diff - DiffComputer', () => { ]; assertDiff(original, modified, expected, true, false); }); + + test('issue #42751', () => { + let original = [ + ' 1', + ' 2', + ]; + let modified = [ + ' 1', + ' 3', + ]; + let expected = [ + createLineChange( + 2, 2, 2, 2, + [ + createCharChange(2, 3, 2, 4, 2, 3, 2, 5) + ] + ) + ]; + assertDiff(original, modified, expected, true, false); + }); }); diff --git a/src/vs/platform/driver/electron-browser/driver.ts b/src/vs/platform/driver/electron-browser/driver.ts index 2508ccbb347d..a03ec9f04638 100644 --- a/src/vs/platform/driver/electron-browser/driver.ts +++ b/src/vs/platform/driver/electron-browser/driver.ts @@ -115,7 +115,18 @@ class WindowDriver implements IWindowDriver { async isActiveElement(selector: string): TPromise { const element = document.querySelector(selector); - return element === document.activeElement; + + if (element !== document.activeElement) { + const el = document.activeElement; + const tagName = el.tagName; + const id = el.id ? `#${el.id}` : ''; + const classes = el.className.split(/\W+/g).map(c => c.trim()).filter(c => !!c).map(c => `.${c}`).join(''); + const current = `${tagName}${id}${classes}`; + + throw new Error(`Active element not found. Current active element is '${current}'`); + } + + return true; } async getElements(selector: string, recursive: boolean): TPromise { diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 17f98c7bf014..10bc66316788 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -488,4 +488,12 @@ declare module 'vscode' { } //#endregion + + //#region Joh -> exclusive document filters + + export interface DocumentFilter { + exclusive?: boolean; + } + + //#endregion } diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index 893b8962517a..1ddb52cbb101 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -11,12 +11,13 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext, IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto -} from '../node/extHost.protocol'; +} from 'vs/workbench/api/node/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers'; import severity from 'vs/base/common/severity'; -import { AbstractDebugAdapter, convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/node/debugAdapter'; +import { AbstractDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; import * as paths from 'vs/base/common/paths'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/common/debugUtils'; @extHostNamedCustomer(MainContext.MainThreadDebugService) diff --git a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts index d496e707c81c..4474c00ee09f 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDocuments.ts @@ -220,11 +220,18 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { return this._fileService.resolveFile(asFileUri).then(stats => { // don't create a new file ontop of an existing file return TPromise.wrapError(new Error('file already exists on disk')); - }, err => this._doCreateUntitled(asFileUri).then(resource => !!resource)); + }, err => { + return this._doCreateUntitled(uri).then(resource => !!resource); + }); } private _doCreateUntitled(resource?: URI, modeId?: string, initialValue?: string): TPromise { - return this._untitledEditorService.loadOrCreate({ resource, modeId, initialValue }).then(model => { + return this._untitledEditorService.loadOrCreate({ + resource, + modeId, + initialValue, + useResourcePath: Boolean(resource && resource.path) + }).then(model => { const resource = model.getResource(); if (!this._modelIsSynced[resource.toString()]) { diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index d35d3e696090..8afaaa63c6cb 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -7,7 +7,7 @@ import { Emitter } from 'vs/base/common/event'; import { TernarySearchTree } from 'vs/base/common/map'; import { score } from 'vs/editor/common/modes/languageSelector'; -import * as Platform from 'vs/base/common/platform'; +import * as platform from 'vs/base/common/platform'; import * as errors from 'vs/base/common/errors'; import product from 'vs/platform/node/product'; import pkg from 'vs/platform/node/package'; @@ -147,18 +147,23 @@ export function createApiFactory( // we cannot say if the extension is doing it right or wrong... let checkSelector = (function () { let done = initData.environment.extensionDevelopmentPath !== extension.extensionFolderPath; - function inform(selector: vscode.DocumentSelector) { - console.info(`Extension '${extension.id}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`); - done = true; + function informOnce(selector: vscode.DocumentSelector) { + if (!done) { + console.info(`Extension '${extension.id}' uses a document selector without scheme. Learn more about this: https://go.microsoft.com/fwlink/?linkid=872305`); + done = true; + } } return function perform(selector: vscode.DocumentSelector): vscode.DocumentSelector { - if (!done) { - if (Array.isArray(selector)) { - selector.forEach(perform); - } else if (typeof selector === 'string') { - inform(selector); - } else if (typeof selector.scheme === 'undefined') { - inform(selector); + if (Array.isArray(selector)) { + selector.forEach(perform); + } else if (typeof selector === 'string') { + informOnce(selector); + } else { + if (typeof selector.scheme === 'undefined') { + informOnce(selector); + } + if (!extension.enableProposedApi && typeof selector.exclusive === 'boolean') { + throwProposedApiError(extension); } } return selector; @@ -215,7 +220,7 @@ export function createApiFactory( const env: typeof vscode.env = Object.freeze({ get machineId() { return initData.telemetryInfo.machineId; }, get sessionId() { return initData.telemetryInfo.sessionId; }, - get language() { return Platform.language; }, + get language() { return platform.language; }, get appName() { return product.nameLong; }, get appRoot() { return initData.environment.appRoot; }, get logLevel() { return extHostLogService.getLevel(); } diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 19423ae82189..ed29c4320edc 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -258,6 +258,7 @@ export interface ISerializedDocumentFilter { language?: string; scheme?: string; pattern?: vscode.GlobPattern; + exclusive?: boolean; } export interface MainThreadLanguageFeaturesShape extends IDisposable { diff --git a/src/vs/workbench/api/node/extHostDebugService.ts b/src/vs/workbench/api/node/extHostDebugService.ts index e85cb0fe1a7a..7b27765e1c83 100644 --- a/src/vs/workbench/api/node/extHostDebugService.ts +++ b/src/vs/workbench/api/node/extHostDebugService.ts @@ -17,7 +17,7 @@ import { import * as vscode from 'vscode'; import { Disposable, Position, Location, SourceBreakpoint, FunctionBreakpoint } from 'vs/workbench/api/node/extHostTypes'; import { generateUuid } from 'vs/base/common/uuid'; -import { DebugAdapter, convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/node/debugAdapter'; +import { DebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; import { ExtHostWorkspace } from 'vs/workbench/api/node/extHostWorkspace'; import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService'; import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors'; @@ -28,6 +28,7 @@ import { VariableResolver } from 'vs/workbench/services/configurationResolver/no import { IConfigurationResolverService } from '../../services/configurationResolver/common/configurationResolver'; import { IStringDictionary } from 'vs/base/common/collections'; import { ExtHostConfiguration } from './extHostConfiguration'; +import { convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/common/debugUtils'; export class ExtHostDebugService implements ExtHostDebugServiceShape { @@ -591,4 +592,4 @@ export class ExtHostVariableResolverService implements IConfigurationResolverSer public executeCommandVariables(configuration: any, variables: IStringDictionary): TPromise> { throw new Error('findAndExecuteCommandVariables not implemented.'); } -} \ No newline at end of file +} diff --git a/src/vs/workbench/api/node/extHostLanguageFeatures.ts b/src/vs/workbench/api/node/extHostLanguageFeatures.ts index a5032c4686cd..4c22a34d548b 100644 --- a/src/vs/workbench/api/node/extHostLanguageFeatures.ts +++ b/src/vs/workbench/api/node/extHostLanguageFeatures.ts @@ -887,7 +887,8 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape { $serialized: true, language: selector.language, scheme: this._transformScheme(selector.scheme), - pattern: selector.pattern + pattern: selector.pattern, + exclusive: selector.exclusive }; } diff --git a/src/vs/workbench/api/node/extHostTypeConverters.ts b/src/vs/workbench/api/node/extHostTypeConverters.ts index 149733b823a0..c8aec09c9dee 100644 --- a/src/vs/workbench/api/node/extHostTypeConverters.ts +++ b/src/vs/workbench/api/node/extHostTypeConverters.ts @@ -696,7 +696,8 @@ function doToLanguageSelector(selector: string | vscode.DocumentFilter): string return { language: selector.language, scheme: selector.scheme, - pattern: toGlobPattern(selector.pattern) + pattern: toGlobPattern(selector.pattern), + exclusive: selector.exclusive }; } diff --git a/src/vs/workbench/browser/parts/editor2/nextTabsTitleControl.ts b/src/vs/workbench/browser/parts/editor2/nextTabsTitleControl.ts index 82bbca4da7b4..38ac7408cc48 100644 --- a/src/vs/workbench/browser/parts/editor2/nextTabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor2/nextTabsTitleControl.ts @@ -364,7 +364,6 @@ export class NextTabsTitleControl extends NextTitleControl { tabContainer.appendChild(tabCloseContainer); const actionRunner = new TabActionRunner(() => this.group.id, index); - this.tabDisposeables.push(actionRunner); const actionBar = new ActionBar(tabCloseContainer, { ariaLabel: localize('araLabelTabActions', "Tab actions"), actionRunner }); actionBar.push(this.closeOneEditorAction, { icon: true, label: false, keybinding: this.getKeybindingLabel(this.closeOneEditorAction) }); @@ -373,7 +372,7 @@ export class NextTabsTitleControl extends NextTitleControl { // Eventing const eventsDisposable = this.hookTabListeners(tabContainer, index); - this.tabDisposeables.push(combinedDisposable([eventsDisposable, actionBar, editorLabel])); + this.tabDisposeables.push(combinedDisposable([eventsDisposable, actionBar, actionRunner, editorLabel])); return tabContainer; } @@ -849,10 +848,10 @@ export class NextTabsTitleControl extends NextTitleControl { private blockRevealActiveTabOnce(): void { - // When closing tabs through the tab close button or gesture, the user - // might want to rapidly close tabs in sequence and as such revealing - // the active tab after each close would be annoying. As such we block - // the automated revealing of the active tab once after the close is + // When closing tabs through the tab close button or gesture, the user + // might want to rapidly close tabs in sequence and as such revealing + // the active tab after each close would be annoying. As such we block + // the automated revealing of the active tab once after the close is // triggered. this.blockRevealActiveTab = true; } diff --git a/src/vs/workbench/parts/debug/browser/baseDebugView.ts b/src/vs/workbench/parts/debug/browser/baseDebugView.ts index 0e30bebf5b77..a15f7d2bb52d 100644 --- a/src/vs/workbench/parts/debug/browser/baseDebugView.ts +++ b/src/vs/workbench/parts/debug/browser/baseDebugView.ts @@ -50,7 +50,7 @@ export function renderViewTree(container: HTMLElement): HTMLElement { return treeContainer; } -function replaceWhitespace(value: string): string { +export function replaceWhitespace(value: string): string { const map: { [x: string]: string } = { '\n': '\\n', '\r': '\\r', '\t': '\\t' }; return value.replace(/[\n\r\t]/g, char => map[char]); } @@ -98,7 +98,7 @@ export function renderExpressionValue(expressionOrValue: IExpression | string, c } } -export function renderVariable(tree: ITree, variable: Variable, data: IVariableTemplateData, showChanged: boolean): void { +export function renderVariable(variable: Variable, data: IVariableTemplateData, showChanged: boolean): void { if (variable.available) { data.name.textContent = replaceWhitespace(variable.name); data.name.title = variable.type ? variable.type : variable.name; diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 7f6ab01d5e21..3479ce64f1ae 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -730,19 +730,3 @@ export interface IDebugEditorContribution extends IEditorContribution { closeBreakpointWidget(): void; addLaunchConfiguration(): TPromise; } - -// utils - -const _formatPIIRegexp = /{([^}]+)}/g; - -export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string { - return value.replace(_formatPIIRegexp, function (match, group) { - if (excludePII && group.length > 0 && group[0] !== '_') { - return match; - } - - return args && args.hasOwnProperty(group) ? - args[group] : - match; - }); -} diff --git a/src/vs/workbench/parts/debug/common/debugSchemas.ts b/src/vs/workbench/parts/debug/common/debugSchemas.ts new file mode 100644 index 000000000000..66479fd753ad --- /dev/null +++ b/src/vs/workbench/parts/debug/common/debugSchemas.ts @@ -0,0 +1,190 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as extensionsRegistry from 'vs/workbench/services/extensions/common/extensionsRegistry'; +import * as nls from 'vs/nls'; +import { IDebuggerContribution, ICompound } from 'vs/workbench/parts/debug/common/debug'; +import { launchSchemaId } from 'vs/workbench/services/configuration/common/configuration'; +import { IJSONSchema } from 'vs/base/common/jsonSchema'; + +// debuggers extension point +export const debuggersExtPoint = extensionsRegistry.ExtensionsRegistry.registerExtensionPoint('debuggers', [], { + description: nls.localize('vscode.extension.contributes.debuggers', 'Contributes debug adapters.'), + type: 'array', + defaultSnippets: [{ body: [{ type: '', extensions: [] }] }], + items: { + type: 'object', + defaultSnippets: [{ body: { type: '', program: '', runtime: '', enableBreakpointsFor: { languageIds: [''] } } }], + properties: { + type: { + description: nls.localize('vscode.extension.contributes.debuggers.type', "Unique identifier for this debug adapter."), + type: 'string' + }, + label: { + description: nls.localize('vscode.extension.contributes.debuggers.label', "Display name for this debug adapter."), + type: 'string' + }, + program: { + description: nls.localize('vscode.extension.contributes.debuggers.program', "Path to the debug adapter program. Path is either absolute or relative to the extension folder."), + type: 'string' + }, + args: { + description: nls.localize('vscode.extension.contributes.debuggers.args', "Optional arguments to pass to the adapter."), + type: 'array' + }, + runtime: { + description: nls.localize('vscode.extension.contributes.debuggers.runtime', "Optional runtime in case the program attribute is not an executable but requires a runtime."), + type: 'string' + }, + runtimeArgs: { + description: nls.localize('vscode.extension.contributes.debuggers.runtimeArgs', "Optional runtime arguments."), + type: 'array' + }, + variables: { + description: nls.localize('vscode.extension.contributes.debuggers.variables', "Mapping from interactive variables (e.g ${action.pickProcess}) in `launch.json` to a command."), + type: 'object' + }, + initialConfigurations: { + description: nls.localize('vscode.extension.contributes.debuggers.initialConfigurations', "Configurations for generating the initial \'launch.json\'."), + type: ['array', 'string'], + }, + languages: { + description: nls.localize('vscode.extension.contributes.debuggers.languages', "List of languages for which the debug extension could be considered the \"default debugger\"."), + type: 'array' + }, + adapterExecutableCommand: { + description: nls.localize('vscode.extension.contributes.debuggers.adapterExecutableCommand', "If specified VS Code will call this command to determine the executable path of the debug adapter and the arguments to pass."), + type: 'string' + }, + configurationSnippets: { + description: nls.localize('vscode.extension.contributes.debuggers.configurationSnippets', "Snippets for adding new configurations in \'launch.json\'."), + type: 'array' + }, + configurationAttributes: { + description: nls.localize('vscode.extension.contributes.debuggers.configurationAttributes', "JSON schema configurations for validating \'launch.json\'."), + type: 'object' + }, + windows: { + description: nls.localize('vscode.extension.contributes.debuggers.windows', "Windows specific settings."), + type: 'object', + properties: { + runtime: { + description: nls.localize('vscode.extension.contributes.debuggers.windows.runtime', "Runtime used for Windows."), + type: 'string' + } + } + }, + osx: { + description: nls.localize('vscode.extension.contributes.debuggers.osx', "macOS specific settings."), + type: 'object', + properties: { + runtime: { + description: nls.localize('vscode.extension.contributes.debuggers.osx.runtime', "Runtime used for macOS."), + type: 'string' + } + } + }, + linux: { + description: nls.localize('vscode.extension.contributes.debuggers.linux', "Linux specific settings."), + type: 'object', + properties: { + runtime: { + description: nls.localize('vscode.extension.contributes.debuggers.linux.runtime', "Runtime used for Linux."), + type: 'string' + } + } + } + } + } +}); + +export interface IRawBreakpointContribution { + language: string; +} + +// breakpoints extension point #9037 +export const breakpointsExtPoint = extensionsRegistry.ExtensionsRegistry.registerExtensionPoint('breakpoints', [], { + description: nls.localize('vscode.extension.contributes.breakpoints', 'Contributes breakpoints.'), + type: 'array', + defaultSnippets: [{ body: [{ language: '' }] }], + items: { + type: 'object', + defaultSnippets: [{ body: { language: '' } }], + properties: { + language: { + description: nls.localize('vscode.extension.contributes.breakpoints.language', "Allow breakpoints for this language."), + type: 'string' + }, + } + } +}); + +// debug general schema +const defaultCompound: ICompound = { name: 'Compound', configurations: [] }; +export const launchSchema: IJSONSchema = { + id: launchSchemaId, + type: 'object', + title: nls.localize('app.launch.json.title', "Launch"), + required: [], + default: { version: '0.2.0', configurations: [], compounds: [] }, + properties: { + version: { + type: 'string', + description: nls.localize('app.launch.json.version', "Version of this file format."), + default: '0.2.0' + }, + configurations: { + type: 'array', + description: nls.localize('app.launch.json.configurations', "List of configurations. Add new configurations or edit existing ones by using IntelliSense."), + items: { + defaultSnippets: [], + 'type': 'object', + oneOf: [] + } + }, + compounds: { + type: 'array', + description: nls.localize('app.launch.json.compounds', "List of compounds. Each compound references multiple configurations which will get launched together."), + items: { + type: 'object', + required: ['name', 'configurations'], + properties: { + name: { + type: 'string', + description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.") + }, + configurations: { + type: 'array', + default: [], + items: { + oneOf: [{ + enum: [], + description: nls.localize('useUniqueNames', "Please use unique configuration names.") + }, { + type: 'object', + required: ['name'], + properties: { + name: { + enum: [], + description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.") + }, + folder: { + enum: [], + description: nls.localize('app.launch.json.compound.folder', "Name of folder in which the compound is located.") + } + } + }] + }, + description: nls.localize('app.launch.json.compounds.configurations', "Names of configurations that will be started as part of this compound.") + } + }, + default: defaultCompound + }, + default: [ + defaultCompound + ] + } + } +}; diff --git a/src/vs/workbench/parts/debug/common/debugUtils.ts b/src/vs/workbench/parts/debug/common/debugUtils.ts new file mode 100644 index 000000000000..e3c78db313c6 --- /dev/null +++ b/src/vs/workbench/parts/debug/common/debugUtils.ts @@ -0,0 +1,143 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const _formatPIIRegexp = /{([^}]+)}/g; + +export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string { + return value.replace(_formatPIIRegexp, function (match, group) { + if (excludePII && group.length > 0 && group[0] !== '_') { + return match; + } + + return args && args.hasOwnProperty(group) ? + args[group] : + match; + }); +} + +export function getExactExpressionStartAndEnd(lineContent: string, looseStart: number, looseEnd: number): { start: number, end: number } { + let matchingExpression: string = undefined; + let startOffset = 0; + + // Some example supported expressions: myVar.prop, a.b.c.d, myVar?.prop, myVar->prop, MyClass::StaticProp, *myVar + // Match any character except a set of characters which often break interesting sub-expressions + let expression: RegExp = /([^()\[\]{}<>\s+\-/%~#^;=|,`!]|\->)+/g; + let result: RegExpExecArray = undefined; + + // First find the full expression under the cursor + while (result = expression.exec(lineContent)) { + let start = result.index + 1; + let end = start + result[0].length; + + if (start <= looseStart && end >= looseEnd) { + matchingExpression = result[0]; + startOffset = start; + break; + } + } + + // If there are non-word characters after the cursor, we want to truncate the expression then. + // For example in expression 'a.b.c.d', if the focus was under 'b', 'a.b' would be evaluated. + if (matchingExpression) { + let subExpression: RegExp = /\w+/g; + let subExpressionResult: RegExpExecArray = undefined; + while (subExpressionResult = subExpression.exec(matchingExpression)) { + let subEnd = subExpressionResult.index + 1 + startOffset + subExpressionResult[0].length; + if (subEnd >= looseEnd) { + break; + } + } + + if (subExpressionResult) { + matchingExpression = matchingExpression.substring(0, subExpression.lastIndex); + } + } + + return matchingExpression ? + { start: startOffset, end: startOffset + matchingExpression.length - 1 } : + { start: 0, end: 0 }; +} + +// path hooks helpers + +export function convertToDAPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void): void { + convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { + if (toDA && source) { + fixSourcePaths(source); + } + }); +} + +export function convertToVSCPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void): void { + convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { + if (!toDA && source) { + fixSourcePaths(source); + } + }); +} + +function convertPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (toDA: boolean, source: DebugProtocol.Source | undefined) => void): void { + switch (msg.type) { + case 'event': + const event = msg; + switch (event.event) { + case 'output': + fixSourcePaths(false, (event).body.source); + break; + case 'loadedSource': + fixSourcePaths(false, (event).body.source); + break; + case 'breakpoint': + fixSourcePaths(false, (event).body.breakpoint.source); + break; + default: + break; + } + break; + case 'request': + const request = msg; + switch (request.command) { + case 'setBreakpoints': + fixSourcePaths(true, (request.arguments).source); + break; + case 'source': + fixSourcePaths(true, (request.arguments).source); + break; + case 'gotoTargets': + fixSourcePaths(true, (request.arguments).source); + break; + default: + break; + } + break; + case 'response': + const response = msg; + switch (response.command) { + case 'stackTrace': + const r1 = response; + r1.body.stackFrames.forEach(frame => fixSourcePaths(false, frame.source)); + break; + case 'loadedSources': + const r2 = response; + r2.body.sources.forEach(source => fixSourcePaths(false, source)); + break; + case 'scopes': + const r3 = response; + r3.body.scopes.forEach(scope => fixSourcePaths(false, scope.source)); + break; + case 'setFunctionBreakpoints': + const r4 = response; + r4.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); + break; + case 'setBreakpoints': + const r5 = response; + r5.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); + break; + default: + break; + } + break; + } +} diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index 9614c85cc973..2f641ac24566 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -16,16 +16,13 @@ import { ITextModel } from 'vs/editor/common/model'; import { IEditor } from 'vs/platform/editor/common/editor'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import * as extensionsRegistry from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IDebugConfigurationProvider, IDebuggerContribution, ICompound, IDebugConfiguration, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter, ITerminalSettings, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug'; +import { IDebugConfigurationProvider, ICompound, IDebugConfiguration, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter, ITerminalSettings, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug'; import { Debugger } from 'vs/workbench/parts/debug/node/debugger'; import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; @@ -34,189 +31,13 @@ import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { launchSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { TerminalLauncher } from 'vs/workbench/parts/debug/electron-browser/terminalSupport'; - -// debuggers extension point -export const debuggersExtPoint = extensionsRegistry.ExtensionsRegistry.registerExtensionPoint('debuggers', [], { - description: nls.localize('vscode.extension.contributes.debuggers', 'Contributes debug adapters.'), - type: 'array', - defaultSnippets: [{ body: [{ type: '', extensions: [] }] }], - items: { - type: 'object', - defaultSnippets: [{ body: { type: '', program: '', runtime: '', enableBreakpointsFor: { languageIds: [''] } } }], - properties: { - type: { - description: nls.localize('vscode.extension.contributes.debuggers.type', "Unique identifier for this debug adapter."), - type: 'string' - }, - label: { - description: nls.localize('vscode.extension.contributes.debuggers.label', "Display name for this debug adapter."), - type: 'string' - }, - program: { - description: nls.localize('vscode.extension.contributes.debuggers.program', "Path to the debug adapter program. Path is either absolute or relative to the extension folder."), - type: 'string' - }, - args: { - description: nls.localize('vscode.extension.contributes.debuggers.args', "Optional arguments to pass to the adapter."), - type: 'array' - }, - runtime: { - description: nls.localize('vscode.extension.contributes.debuggers.runtime', "Optional runtime in case the program attribute is not an executable but requires a runtime."), - type: 'string' - }, - runtimeArgs: { - description: nls.localize('vscode.extension.contributes.debuggers.runtimeArgs', "Optional runtime arguments."), - type: 'array' - }, - variables: { - description: nls.localize('vscode.extension.contributes.debuggers.variables', "Mapping from interactive variables (e.g ${action.pickProcess}) in `launch.json` to a command."), - type: 'object' - }, - initialConfigurations: { - description: nls.localize('vscode.extension.contributes.debuggers.initialConfigurations', "Configurations for generating the initial \'launch.json\'."), - type: ['array', 'string'], - }, - languages: { - description: nls.localize('vscode.extension.contributes.debuggers.languages', "List of languages for which the debug extension could be considered the \"default debugger\"."), - type: 'array' - }, - adapterExecutableCommand: { - description: nls.localize('vscode.extension.contributes.debuggers.adapterExecutableCommand', "If specified VS Code will call this command to determine the executable path of the debug adapter and the arguments to pass."), - type: 'string' - }, - configurationSnippets: { - description: nls.localize('vscode.extension.contributes.debuggers.configurationSnippets', "Snippets for adding new configurations in \'launch.json\'."), - type: 'array' - }, - configurationAttributes: { - description: nls.localize('vscode.extension.contributes.debuggers.configurationAttributes', "JSON schema configurations for validating \'launch.json\'."), - type: 'object' - }, - windows: { - description: nls.localize('vscode.extension.contributes.debuggers.windows', "Windows specific settings."), - type: 'object', - properties: { - runtime: { - description: nls.localize('vscode.extension.contributes.debuggers.windows.runtime', "Runtime used for Windows."), - type: 'string' - } - } - }, - osx: { - description: nls.localize('vscode.extension.contributes.debuggers.osx', "macOS specific settings."), - type: 'object', - properties: { - runtime: { - description: nls.localize('vscode.extension.contributes.debuggers.osx.runtime', "Runtime used for macOS."), - type: 'string' - } - } - }, - linux: { - description: nls.localize('vscode.extension.contributes.debuggers.linux', "Linux specific settings."), - type: 'object', - properties: { - runtime: { - description: nls.localize('vscode.extension.contributes.debuggers.linux.runtime', "Runtime used for Linux."), - type: 'string' - } - } - } - } - } -}); - -interface IRawBreakpointContribution { - language: string; -} - -// breakpoints extension point #9037 -const breakpointsExtPoint = extensionsRegistry.ExtensionsRegistry.registerExtensionPoint('breakpoints', [], { - description: nls.localize('vscode.extension.contributes.breakpoints', 'Contributes breakpoints.'), - type: 'array', - defaultSnippets: [{ body: [{ language: '' }] }], - items: { - type: 'object', - defaultSnippets: [{ body: { language: '' } }], - properties: { - language: { - description: nls.localize('vscode.extension.contributes.breakpoints.language', "Allow breakpoints for this language."), - type: 'string' - }, - } - } -}); - -// debug general schema -const defaultCompound: ICompound = { name: 'Compound', configurations: [] }; -const schema: IJSONSchema = { - id: launchSchemaId, - type: 'object', - title: nls.localize('app.launch.json.title', "Launch"), - required: [], - default: { version: '0.2.0', configurations: [], compounds: [] }, - properties: { - version: { - type: 'string', - description: nls.localize('app.launch.json.version', "Version of this file format."), - default: '0.2.0' - }, - configurations: { - type: 'array', - description: nls.localize('app.launch.json.configurations', "List of configurations. Add new configurations or edit existing ones by using IntelliSense."), - items: { - defaultSnippets: [], - 'type': 'object', - oneOf: [] - } - }, - compounds: { - type: 'array', - description: nls.localize('app.launch.json.compounds', "List of compounds. Each compound references multiple configurations which will get launched together."), - items: { - type: 'object', - required: ['name', 'configurations'], - properties: { - name: { - type: 'string', - description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.") - }, - configurations: { - type: 'array', - default: [], - items: { - oneOf: [{ - enum: [], - description: nls.localize('useUniqueNames', "Please use unique configuration names.") - }, { - type: 'object', - required: ['name'], - properties: { - name: { - enum: [], - description: nls.localize('app.launch.json.compound.name', "Name of compound. Appears in the launch configuration drop down menu.") - }, - folder: { - enum: [], - description: nls.localize('app.launch.json.compound.folder', "Name of folder in which the compound is located.") - } - } - }] - }, - description: nls.localize('app.launch.json.compounds.configurations', "Names of configurations that will be started as part of this compound.") - } - }, - default: defaultCompound - }, - default: [ - defaultCompound - ] - } - } -}; +import { Registry } from 'vs/platform/registry/common/platform'; +import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; +import { launchSchema, debuggersExtPoint, breakpointsExtPoint } from 'vs/workbench/parts/debug/common/debugSchemas'; const jsonRegistry = Registry.as(JSONExtensions.JSONContribution); -jsonRegistry.registerSchema(launchSchemaId, schema); +jsonRegistry.registerSchema(launchSchemaId, launchSchema); + const DEBUG_SELECTED_CONFIG_NAME_KEY = 'debug.selectedconfigname'; const DEBUG_SELECTED_ROOT = 'debug.selectedroot'; @@ -373,7 +194,7 @@ export class ConfigurationManager implements IConfigurationManager { // update the schema to include all attributes, snippets and types from extensions. this.debuggers.forEach(adapter => { - const items = (schema.properties['configurations'].items); + const items = (launchSchema.properties['configurations'].items); const schemaAttributes = adapter.getSchemaAttributes(); if (schemaAttributes) { items.oneOf.push(...schemaAttributes); @@ -423,7 +244,7 @@ export class ConfigurationManager implements IConfigurationManager { } private setCompoundSchemaValues(): void { - const compoundConfigurationsSchema = (schema.properties['compounds'].items).properties['configurations']; + const compoundConfigurationsSchema = (launchSchema.properties['compounds'].items).properties['configurations']; const launchNames = this.launches.map(l => l.getConfigurationNames(false)).reduce((first, second) => first.concat(second), []); (compoundConfigurationsSchema.items).oneOf[0].enum = launchNames; @@ -432,7 +253,7 @@ export class ConfigurationManager implements IConfigurationManager { const folderNames = this.contextService.getWorkspace().folders.map(f => f.name); (compoundConfigurationsSchema.items).oneOf[1].properties.folder.enum = folderNames; - jsonRegistry.registerSchema(launchSchemaId, schema); + jsonRegistry.registerSchema(launchSchemaId, launchSchema); } public getLaunches(): ILaunch[] { diff --git a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts index c91609db06ae..9a154574295a 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugHover.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugHover.ts @@ -28,6 +28,7 @@ import { editorHoverBackground, editorHoverBorder } from 'vs/platform/theme/comm import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; +import { getExactExpressionStartAndEnd } from 'vs/workbench/parts/debug/common/debugUtils'; const $ = dom.$; const MAX_ELEMENTS_SHOWN = 18; @@ -138,57 +139,14 @@ export class DebugHoverWidget implements IContentWidget { return this.domNode; } - private getExactExpressionRange(lineContent: string, range: Range): Range { - let matchingExpression: string = undefined; - let startOffset = 0; - - // Some example supported expressions: myVar.prop, a.b.c.d, myVar?.prop, myVar->prop, MyClass::StaticProp, *myVar - // Match any character except a set of characters which often break interesting sub-expressions - let expression: RegExp = /([^()\[\]{}<>\s+\-/%~#^;=|,`!]|\->)+/g; - let result: RegExpExecArray = undefined; - - // First find the full expression under the cursor - while (result = expression.exec(lineContent)) { - let start = result.index + 1; - let end = start + result[0].length; - - if (start <= range.startColumn && end >= range.endColumn) { - matchingExpression = result[0]; - startOffset = start; - break; - } - } - - // If there are non-word characters after the cursor, we want to truncate the expression then. - // For example in expression 'a.b.c.d', if the focus was under 'b', 'a.b' would be evaluated. - if (matchingExpression) { - let subExpression: RegExp = /\w+/g; - let subExpressionResult: RegExpExecArray = undefined; - while (subExpressionResult = subExpression.exec(matchingExpression)) { - let subEnd = subExpressionResult.index + 1 + startOffset + subExpressionResult[0].length; - if (subEnd >= range.endColumn) { - break; - } - } - - if (subExpressionResult) { - matchingExpression = matchingExpression.substring(0, subExpression.lastIndex); - } - } - - return matchingExpression ? - new Range(range.startLineNumber, startOffset, range.endLineNumber, startOffset + matchingExpression.length - 1) : - new Range(range.startLineNumber, 0, range.endLineNumber, 0); - } - public showAt(range: Range, focus: boolean): TPromise { const pos = range.getStartPosition(); const process = this.debugService.getViewModel().focusedProcess; const lineContent = this.editor.getModel().getLineContent(pos.lineNumber); - const expressionRange = this.getExactExpressionRange(lineContent, range); + const { start, end } = getExactExpressionStartAndEnd(lineContent, range.startColumn, range.endColumn); // use regex to extract the sub-expression #9821 - const matchingExpression = lineContent.substring(expressionRange.startColumn - 1, expressionRange.endColumn); + const matchingExpression = lineContent.substring(start - 1, end); if (!matchingExpression) { return TPromise.as(this.hide()); } @@ -198,7 +156,7 @@ export class DebugHoverWidget implements IContentWidget { const result = new Expression(matchingExpression); promise = result.evaluate(process, this.debugService.getViewModel().focusedStackFrame, 'hover').then(() => result); } else { - promise = this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word), expressionRange); + promise = this.findExpressionInStackFrame(matchingExpression.split('.').map(word => word.trim()).filter(word => !!word)); } return promise.then(expression => { @@ -208,7 +166,7 @@ export class DebugHoverWidget implements IContentWidget { } this.highlightDecorations = this.editor.deltaDecorations(this.highlightDecorations, [{ - range: new Range(pos.lineNumber, expressionRange.startColumn, pos.lineNumber, expressionRange.startColumn + matchingExpression.length), + range: new Range(pos.lineNumber, start, pos.lineNumber, start + matchingExpression.length), options: DebugHoverWidget._HOVER_HIGHLIGHT_DECORATION_OPTIONS }]); @@ -240,7 +198,7 @@ export class DebugHoverWidget implements IContentWidget { }); } - private findExpressionInStackFrame(namesToFind: string[], expressionRange: Range): TPromise { + private findExpressionInStackFrame(namesToFind: string[]): TPromise { return this.debugService.getViewModel().focusedStackFrame.getScopes() .then(scopes => scopes.filter(s => !s.expensive)) .then(scopes => TPromise.join(scopes.map(scope => this.doFindExpression(scope, namesToFind)))) diff --git a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts index 4a0e8e4639ea..66eabe1f91c1 100644 --- a/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts +++ b/src/vs/workbench/parts/debug/electron-browser/rawDebugSession.ts @@ -17,6 +17,7 @@ import { IOutputService } from 'vs/workbench/parts/output/common/output'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { StreamDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter'; +import { formatPII } from 'vs/workbench/parts/debug/common/debugUtils'; export interface SessionExitedEvent extends debug.DebugEvent { @@ -211,7 +212,7 @@ export class RawDebugSession implements debug.ISession { const promise = this.internalSend(command, args).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => { const error = errorResponse && errorResponse.body ? errorResponse.body.error : null; const errorMessage = errorResponse ? errorResponse.message : ''; - const telemetryMessage = error ? debug.formatPII(error.format, true, error.variables) : errorMessage; + const telemetryMessage = error ? formatPII(error.format, true, error.variables) : errorMessage; if (error && error.sendTelemetry) { /* __GDPR__ "debugProtocolErrorResponse" : { @@ -228,7 +229,7 @@ export class RawDebugSession implements debug.ISession { } } - const userMessage = error ? debug.formatPII(error.format, false, error.variables) : errorMessage; + const userMessage = error ? formatPII(error.format, false, error.variables) : errorMessage; if (error && error.url) { const label = error.urlLabel ? error.urlLabel : nls.localize('moreInfo', "More Info"); return TPromise.wrapError(errors.create(userMessage, { diff --git a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts index adba2939768c..b285d27ddea6 100644 --- a/src/vs/workbench/parts/debug/electron-browser/replViewer.ts +++ b/src/vs/workbench/parts/debug/electron-browser/replViewer.ts @@ -223,7 +223,7 @@ export class ReplExpressionsRenderer implements IRenderer { public renderElement(tree: ITree, element: any, templateId: string, templateData: any): void { if (templateId === ReplExpressionsRenderer.VARIABLE_TEMPLATE_ID) { - renderVariable(tree, element, templateData, false); + renderVariable(element, templateData, false); } else if (templateId === ReplExpressionsRenderer.EXPRESSION_TEMPLATE_ID) { this.renderExpression(tree, element, templateData); } else if (templateId === ReplExpressionsRenderer.SIMPLE_REPL_ELEMENT_TEMPLATE_ID) { diff --git a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts index 35d23cdcf36c..9ade1f87f61c 100644 --- a/src/vs/workbench/parts/debug/electron-browser/variablesView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/variablesView.ts @@ -284,7 +284,7 @@ export class VariablesRenderer implements IRenderer { } }); } else { - renderVariable(tree, variable, templateData, true); + renderVariable(variable, templateData, true); } } } diff --git a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts index 9cd0b0c85fd9..53bb57a640c6 100644 --- a/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts +++ b/src/vs/workbench/parts/debug/electron-browser/watchExpressionsView.ts @@ -284,7 +284,7 @@ class WatchExpressionsRenderer implements IRenderer { if (templateId === WatchExpressionsRenderer.WATCH_EXPRESSION_TEMPLATE_ID) { this.renderWatchExpression(tree, element, templateData); } else { - renderVariable(tree, element, templateData, true); + renderVariable(element, templateData, true); } } diff --git a/src/vs/workbench/parts/debug/node/debugAdapter.ts b/src/vs/workbench/parts/debug/node/debugAdapter.ts index f3cc2f9fcab6..8e82578a9b2e 100644 --- a/src/vs/workbench/parts/debug/node/debugAdapter.ts +++ b/src/vs/workbench/parts/debug/node/debugAdapter.ts @@ -220,13 +220,13 @@ export abstract class StreamDebugAdapter extends AbstractDebugAdapter { */ export class DebugAdapter extends StreamDebugAdapter { - private _serverProcess: cp.ChildProcess; + private serverProcess: cp.ChildProcess; - constructor(private _debugType: string, private _adapterExecutable: IAdapterExecutable | null, extensionDescriptions: IExtensionDescription[], private _outputService?: IOutputService) { + constructor(private debugType: string, private adapterExecutable: IAdapterExecutable | null, extensionDescriptions: IExtensionDescription[], private outputService?: IOutputService) { super(); - if (!this._adapterExecutable) { - this._adapterExecutable = DebugAdapter.platformAdapterExecutable(extensionDescriptions, this._debugType); + if (!this.adapterExecutable) { + this.adapterExecutable = DebugAdapter.platformAdapterExecutable(extensionDescriptions, this.debugType); } } @@ -235,54 +235,54 @@ export class DebugAdapter extends StreamDebugAdapter { return new TPromise((c, e) => { // verify executables - if (this._adapterExecutable.command) { - if (paths.isAbsolute(this._adapterExecutable.command)) { - if (!fs.existsSync(this._adapterExecutable.command)) { - e(new Error(nls.localize('debugAdapterBinNotFound', "Debug adapter executable '{0}' does not exist.", this._adapterExecutable.command))); + if (this.adapterExecutable.command) { + if (paths.isAbsolute(this.adapterExecutable.command)) { + if (!fs.existsSync(this.adapterExecutable.command)) { + e(new Error(nls.localize('debugAdapterBinNotFound', "Debug adapter executable '{0}' does not exist.", this.adapterExecutable.command))); } } else { // relative path - if (this._adapterExecutable.command.indexOf('/') < 0 && this._adapterExecutable.command.indexOf('\\') < 0) { + if (this.adapterExecutable.command.indexOf('/') < 0 && this.adapterExecutable.command.indexOf('\\') < 0) { // no separators: command looks like a runtime name like 'node' or 'mono' // TODO: check that the runtime is available on PATH } } } else { e(new Error(nls.localize({ key: 'debugAdapterCannotDetermineExecutable', comment: ['Adapter executable file not found'] }, - "Cannot determine executable for debug adapter '{0}'.", this._debugType))); + "Cannot determine executable for debug adapter '{0}'.", this.debugType))); } - if (this._adapterExecutable.command === 'node' && this._outputService) { - if (Array.isArray(this._adapterExecutable.args) && this._adapterExecutable.args.length > 0) { - stdfork.fork(this._adapterExecutable.args[0], this._adapterExecutable.args.slice(1), {}, (err, child) => { + if (this.adapterExecutable.command === 'node' && this.outputService) { + if (Array.isArray(this.adapterExecutable.args) && this.adapterExecutable.args.length > 0) { + stdfork.fork(this.adapterExecutable.args[0], this.adapterExecutable.args.slice(1), {}, (err, child) => { if (err) { - e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this._adapterExecutable.args[0]))); + e(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this.adapterExecutable.args[0]))); } - this._serverProcess = child; + this.serverProcess = child; c(null); }); } else { e(new Error(nls.localize('unableToLaunchDebugAdapterNoArgs', "Unable to launch debug adapter."))); } } else { - this._serverProcess = cp.spawn(this._adapterExecutable.command, this._adapterExecutable.args); + this.serverProcess = cp.spawn(this.adapterExecutable.command, this.adapterExecutable.args); c(null); } }).then(_ => { - this._serverProcess.on('error', (err: Error) => this._onError.fire(err)); - this._serverProcess.on('exit', (code: number, signal: string) => this._onExit.fire(code)); + this.serverProcess.on('error', (err: Error) => this._onError.fire(err)); + this.serverProcess.on('exit', (code: number, signal: string) => this._onExit.fire(code)); - if (this._outputService) { + if (this.outputService) { const sanitize = (s: string) => s.toString().replace(/\r?\n$/mg, ''); // this.serverProcess.stdout.on('data', (data: string) => { // console.log('%c' + sanitize(data), 'background: #ddd; font-style: italic;'); // }); - this._serverProcess.stderr.on('data', (data: string) => { - this._outputService.getChannel(ExtensionsChannelId).append(sanitize(data)); + this.serverProcess.stderr.on('data', (data: string) => { + this.outputService.getChannel(ExtensionsChannelId).append(sanitize(data)); }); } - this.connect(this._serverProcess.stdout, this._serverProcess.stdin); + this.connect(this.serverProcess.stdout, this.serverProcess.stdin); }, err => { this._onError.fire(err); }); @@ -295,7 +295,7 @@ export class DebugAdapter extends StreamDebugAdapter { // processes. Therefore we use TASKKILL.EXE if (platform.isWindows) { return new TPromise((c, e) => { - const killer = cp.exec(`taskkill /F /T /PID ${this._serverProcess.pid}`, function (err, stdout, stderr) { + const killer = cp.exec(`taskkill /F /T /PID ${this.serverProcess.pid}`, function (err, stdout, stderr) { if (err) { return e(err); } @@ -304,7 +304,7 @@ export class DebugAdapter extends StreamDebugAdapter { killer.on('error', e); }); } else { - this._serverProcess.kill('SIGTERM'); + this.serverProcess.kill('SIGTERM'); return TPromise.as(null); } } @@ -313,8 +313,8 @@ export class DebugAdapter extends StreamDebugAdapter { if (!contribution) { return undefined; } - let result: IDebuggerContribution = {}; + const result: IDebuggerContribution = Object.create(null); if (contribution.runtime) { if (contribution.runtime.indexOf('./') === 0) { // TODO result.runtime = paths.join(extensionFolderPath, contribution.runtime); @@ -354,10 +354,8 @@ export class DebugAdapter extends StreamDebugAdapter { return result; } - static platformAdapterExecutable(extensionDescriptions: IExtensionDescription[], debugType: string): IAdapterExecutable { - - let result: IDebuggerContribution = {}; - + public static platformAdapterExecutable(extensionDescriptions: IExtensionDescription[], debugType: string): IAdapterExecutable { + const result: IDebuggerContribution = Object.create(null); debugType = debugType.toLowerCase(); // merge all contributions into one @@ -365,15 +363,13 @@ export class DebugAdapter extends StreamDebugAdapter { if (ed.contributes) { const debuggers = ed.contributes['debuggers']; if (debuggers && debuggers.length > 0) { - const dbgs = debuggers.filter(d => strings.equalsIgnoreCase(d.type, debugType)); - for (const dbg of dbgs) { - + debuggers.filter(dbg => strings.equalsIgnoreCase(dbg.type, debugType)).forEach(dbg => { // extract relevant attributes and make then absolute where needed - const dbg1 = DebugAdapter.extract(dbg, ed.extensionFolderPath); + const extractedDbg = DebugAdapter.extract(dbg, ed.extensionFolderPath); // merge - objects.mixin(result, dbg1, ed.isBuiltin); - } + objects.mixin(result, extractedDbg, ed.isBuiltin); + }); } } } @@ -432,85 +428,3 @@ export class DebugAdapter extends StreamDebugAdapter { return resolverService.resolveAny(workspaceFolder, result, commandValueMapping); } } - -// path hooks helpers - -export function convertToDAPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void): void { - convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { - if (toDA && source) { - fixSourcePaths(source); - } - }); -} - -export function convertToVSCPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (source: DebugProtocol.Source) => void): void { - convertPaths(msg, (toDA: boolean, source: DebugProtocol.Source | undefined) => { - if (!toDA && source) { - fixSourcePaths(source); - } - }); -} - -function convertPaths(msg: DebugProtocol.ProtocolMessage, fixSourcePaths: (toDA: boolean, source: DebugProtocol.Source | undefined) => void): void { - switch (msg.type) { - case 'event': - const event = msg; - switch (event.event) { - case 'output': - fixSourcePaths(false, (event).body.source); - break; - case 'loadedSource': - fixSourcePaths(false, (event).body.source); - break; - case 'breakpoint': - fixSourcePaths(false, (event).body.breakpoint.source); - break; - default: - break; - } - break; - case 'request': - const request = msg; - switch (request.command) { - case 'setBreakpoints': - fixSourcePaths(true, (request.arguments).source); - break; - case 'source': - fixSourcePaths(true, (request.arguments).source); - break; - case 'gotoTargets': - fixSourcePaths(true, (request.arguments).source); - break; - default: - break; - } - break; - case 'response': - const response = msg; - switch (response.command) { - case 'stackTrace': - const r1 = response; - r1.body.stackFrames.forEach(frame => fixSourcePaths(false, frame.source)); - break; - case 'loadedSources': - const r2 = response; - r2.body.sources.forEach(source => fixSourcePaths(false, source)); - break; - case 'scopes': - const r3 = response; - r3.body.scopes.forEach(scope => fixSourcePaths(false, scope.source)); - break; - case 'setFunctionBreakpoints': - const r4 = response; - r4.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); - break; - case 'setBreakpoints': - const r5 = response; - r5.body.breakpoints.forEach(bp => fixSourcePaths(false, bp.source)); - break; - default: - break; - } - break; - } -} diff --git a/src/vs/workbench/parts/debug/node/debugger.ts b/src/vs/workbench/parts/debug/node/debugger.ts index 3a637954e123..2dcd96f5421a 100644 --- a/src/vs/workbench/parts/debug/node/debugger.ts +++ b/src/vs/workbench/parts/debug/node/debugger.ts @@ -19,14 +19,14 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati export class Debugger { - private _mergedExtensionDescriptions: IExtensionDescription[]; + private mergedExtensionDescriptions: IExtensionDescription[]; constructor(private configurationManager: IConfigurationManager, private debuggerContribution: IDebuggerContribution, public extensionDescription: IExtensionDescription, @IConfigurationService private configurationService: IConfigurationService, @ICommandService private commandService: ICommandService, @IConfigurationResolverService private configurationResolverService: IConfigurationResolverService, ) { - this._mergedExtensionDescriptions = [extensionDescription]; + this.mergedExtensionDescriptions = [extensionDescription]; } public hasConfigurationProvider = false; @@ -37,7 +37,7 @@ export class Debugger { if (debugConfigs.extensionHostDebugAdapter) { return this.configurationManager.createDebugAdapter(this.type, adapterExecutable); } else { - return new DebugAdapter(this.type, adapterExecutable, this._mergedExtensionDescriptions, outputService); + return new DebugAdapter(this.type, adapterExecutable, this.mergedExtensionDescriptions, outputService); } }); } @@ -118,7 +118,7 @@ export class Debugger { public merge(secondRawAdapter: IDebuggerContribution, extensionDescription: IExtensionDescription): void { // remember all ext descriptions that are the source of this debugger - this._mergedExtensionDescriptions.push(extensionDescription); + this.mergedExtensionDescriptions.push(extensionDescription); // Give priority to built in debug adapters if (extensionDescription.isBuiltin) { diff --git a/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts b/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts new file mode 100644 index 000000000000..30feb53f8f9c --- /dev/null +++ b/src/vs/workbench/parts/debug/test/browser/baseDebugView.test.ts @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { replaceWhitespace, renderExpressionValue, renderVariable } from 'vs/workbench/parts/debug/browser/baseDebugView'; +import * as dom from 'vs/base/browser/dom'; +import { Expression, Variable, Process, Scope, StackFrame, Thread } from 'vs/workbench/parts/debug/common/debugModel'; +import { MockSession } from 'vs/workbench/parts/debug/test/common/mockDebug'; +const $ = dom.$; + +suite('Debug - Base Debug View', () => { + + test('replace whitespace', () => { + assert.equal(replaceWhitespace('hey there'), 'hey there'); + assert.equal(replaceWhitespace('hey there\n'), 'hey there\\n'); + assert.equal(replaceWhitespace('hey \r there\n\t'), 'hey \\r there\\n\\t'); + assert.equal(replaceWhitespace('hey \r\t\n\t\t\n there'), 'hey \\r\\t\\n\\t\\t\\n there'); + }); + + test('render expression value', () => { + let container = $('.container'); + renderExpressionValue('render \n me', container, { showHover: true, preserveWhitespace: true }); + assert.equal(container.className, 'value'); + assert.equal(container.title, 'render \n me'); + assert.equal(container.textContent, 'render \n me'); + + const expression = new Expression('console'); + expression.value = 'Object'; + container = $('.container'); + renderExpressionValue(expression, container, { colorize: true }); + assert.equal(container.className, 'value unavailable error'); + + expression.available = true; + expression.value = '"string value"'; + container = $('.container'); + renderExpressionValue(expression, container, { colorize: true }); + assert.equal(container.className, 'value string'); + assert.equal(container.textContent, '"string value"'); + + expression.type = 'boolean'; + container = $('.container'); + renderExpressionValue(expression, container, { colorize: true }); + assert.equal(container.className, 'value boolean'); + assert.equal(container.textContent, expression.value); + + expression.value = 'this is a long string'; + container = $('.container'); + renderExpressionValue(expression, container, { colorize: true, maxValueLength: 4 }); + assert.equal(container.textContent, 'this...'); + }); + + test('render variable', () => { + const rawSession = new MockSession(); + const process = new Process({ name: 'mockProcess', type: 'node', request: 'launch' }, rawSession); + const thread = new Thread(process, 'mockthread', 1); + const stackFrame = new StackFrame(thread, 1, null, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: undefined, endColumn: undefined }, 0); + const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10); + + let variable = new Variable(process, scope, 2, 'foo', 'bar.foo', undefined, 0, 0, {}, 'string'); + let expression = $('.'); + let name = $('.'); + let value = $('.'); + renderVariable(variable, { expression, name, value }, false); + + assert.equal(name.textContent, 'foo'); + assert.equal(value.textContent, ''); + assert.equal(value.title, ''); + + variable.value = 'hey'; + expression = $('.'); + name = $('.'); + value = $('.'); + renderVariable(variable, { expression, name, value }, false); + assert.equal(value.textContent, 'hey'); + assert.equal(name.textContent, 'foo:'); + assert.equal(name.title, 'string'); + + variable = new Variable(process, scope, 2, 'console', 'console', '5', 0, 0, { kind: 'virtual' }); + expression = $('.'); + name = $('.'); + value = $('.'); + renderVariable(variable, { expression, name, value }, false); + assert.equal(name.className, 'virtual'); + assert.equal(name.textContent, 'console:'); + assert.equal(name.title, 'console'); + assert.equal(value.className, 'value number'); + }); +}); diff --git a/src/vs/workbench/parts/debug/test/common/debugSource.test.ts b/src/vs/workbench/parts/debug/test/common/debugSource.test.ts index 072ee84d214a..a2f305ffa68a 100644 --- a/src/vs/workbench/parts/debug/test/common/debugSource.test.ts +++ b/src/vs/workbench/parts/debug/test/common/debugSource.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import uri from 'vs/base/common/uri'; import { Source } from 'vs/workbench/parts/debug/common/debugSource'; +import { normalize } from 'vs/base/common/paths'; suite('Debug - Source', () => { @@ -37,4 +38,22 @@ suite('Debug - Source', () => { assert.equal(source.reference, 11); assert.equal(source.uri.toString(), 'debug:internalModule.js?session%3DaDebugSessionId%26ref%3D11'); }); + + test('get encoded debug data', () => { + const checkData = (uri: uri, expectedName, expectedPath, expectedSourceReference, expectedProcessId) => { + let { name, path, sourceReference, processId } = Source.getEncodedDebugData(uri); + assert.equal(name, expectedName); + assert.equal(path, expectedPath); + assert.equal(sourceReference, expectedSourceReference); + assert.equal(processId, expectedProcessId); + }; + + checkData(uri.file('a/b/c/d'), 'd', normalize('/a/b/c/d', true), undefined, undefined); + checkData(uri.from({ scheme: 'file', path: '/my/path/test.js', query: 'ref=1&session=2' }), 'test.js', normalize('/my/path/test.js', true), undefined, undefined); + + checkData(uri.from({ scheme: 'http', authority: 'www.msft.com', path: '/my/path' }), 'path', 'http://www.msft.com/my/path', undefined, undefined); + checkData(uri.from({ scheme: 'debug', authority: 'www.msft.com', path: '/my/path', query: 'ref=100' }), 'path', '/my/path', 100, undefined); + checkData(uri.from({ scheme: 'debug', path: 'a/b/c/d.js', query: 'session=100' }), 'd.js', 'a/b/c/d.js', undefined, 100); + checkData(uri.from({ scheme: 'debug', path: 'a/b/c/d/foo.txt', query: 'session=100&ref=10' }), 'foo.txt', 'a/b/c/d/foo.txt', 10, 100); + }); }); diff --git a/src/vs/workbench/parts/debug/test/common/debugUtils.test.ts b/src/vs/workbench/parts/debug/test/common/debugUtils.test.ts index e9c9390ec897..8d953ae7052d 100644 --- a/src/vs/workbench/parts/debug/test/common/debugUtils.test.ts +++ b/src/vs/workbench/parts/debug/test/common/debugUtils.test.ts @@ -3,18 +3,38 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as debug from 'vs/workbench/parts/debug/common/debug'; import * as assert from 'assert'; +import { formatPII, getExactExpressionStartAndEnd } from 'vs/workbench/parts/debug/common/debugUtils'; suite('Debug - Utils', () => { test('formatPII', () => { - assert.strictEqual(debug.formatPII('Foo Bar', false, {}), 'Foo Bar'); - assert.strictEqual(debug.formatPII('Foo {key} Bar', false, {}), 'Foo {key} Bar'); - assert.strictEqual(debug.formatPII('Foo {key} Bar', false, { 'key': 'yes' }), 'Foo yes Bar'); - assert.strictEqual(debug.formatPII('Foo {_0} Bar {_0}', true, { '_0': 'yes' }), 'Foo yes Bar yes'); - assert.strictEqual(debug.formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes' }), 'Foo yes Bar {1}{2}'); - assert.strictEqual(debug.formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes', '1': 'undefined' }), 'Foo yes Bar undefined{2}'); - assert.strictEqual(debug.formatPII('Foo {_key0} Bar {key1}{key2}', true, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar {key1}{key2}'); - assert.strictEqual(debug.formatPII('Foo {_key0} Bar {key1}{key2}', false, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar 5false'); + assert.strictEqual(formatPII('Foo Bar', false, {}), 'Foo Bar'); + assert.strictEqual(formatPII('Foo {key} Bar', false, {}), 'Foo {key} Bar'); + assert.strictEqual(formatPII('Foo {key} Bar', false, { 'key': 'yes' }), 'Foo yes Bar'); + assert.strictEqual(formatPII('Foo {_0} Bar {_0}', true, { '_0': 'yes' }), 'Foo yes Bar yes'); + assert.strictEqual(formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes' }), 'Foo yes Bar {1}{2}'); + assert.strictEqual(formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes', '1': 'undefined' }), 'Foo yes Bar undefined{2}'); + assert.strictEqual(formatPII('Foo {_key0} Bar {key1}{key2}', true, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar {key1}{key2}'); + assert.strictEqual(formatPII('Foo {_key0} Bar {key1}{key2}', false, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar 5false'); }); -}); \ No newline at end of file + + test('getExactExpressionStartAndEnd', () => { + assert.deepEqual(getExactExpressionStartAndEnd('foo', 1, 2), { start: 1, end: 3 }); + assert.deepEqual(getExactExpressionStartAndEnd('foo', 1, 3), { start: 1, end: 3 }); + assert.deepEqual(getExactExpressionStartAndEnd('foo', 1, 4), { start: 1, end: 3 }); + assert.deepEqual(getExactExpressionStartAndEnd('this.name = "John"', 1, 10), { start: 1, end: 9 }); + assert.deepEqual(getExactExpressionStartAndEnd('this.name = "John"', 6, 10), { start: 1, end: 9 }); + // Hovers over "address" should pick up this->address + assert.deepEqual(getExactExpressionStartAndEnd('this->address = "Main street"', 6, 10), { start: 1, end: 13 }); + // Hovers over "name" should pick up a.b.c.d.name + assert.deepEqual(getExactExpressionStartAndEnd('var t = a.b.c.d.name', 16, 20), { start: 9, end: 20 }); + assert.deepEqual(getExactExpressionStartAndEnd('MyClass::StaticProp', 10, 20), { start: 1, end: 19 }); + assert.deepEqual(getExactExpressionStartAndEnd('largeNumber = myVar?.prop', 21, 25), { start: 15, end: 25 }); + + // For example in expression 'a.b.c.d', hover was under 'b', 'a.b' should be the exact range + assert.deepEqual(getExactExpressionStartAndEnd('var t = a.b.c.d.name', 11, 12), { start: 9, end: 11 }); + + assert.deepEqual(getExactExpressionStartAndEnd('var t = a.b;c.d.name', 16, 20), { start: 13, end: 20 }); + assert.deepEqual(getExactExpressionStartAndEnd('var t = a.b.c-d.name', 16, 20), { start: 15, end: 20 }); + }); +}); diff --git a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts b/src/vs/workbench/parts/debug/test/node/debugModel.test.ts index b4fc6e4080fd..9ff21b98e394 100644 --- a/src/vs/workbench/parts/debug/test/node/debugModel.test.ts +++ b/src/vs/workbench/parts/debug/test/node/debugModel.test.ts @@ -58,9 +58,10 @@ suite('Debug - Model', () => { assert.equal(model.getBreakpoints().length, 5); const bp = model.getBreakpoints()[0]; const update: any = {}; - update[bp.getId()] = { line: 100, verified: false }; + update[bp.getId()] = { line: 100, verified: true }; model.updateBreakpoints(update); assert.equal(bp.lineNumber, 100); + assert.equal(bp.verified, true); model.enableOrDisableAllBreakpoints(false); model.getBreakpoints().forEach(bp => { @@ -71,6 +72,9 @@ suite('Debug - Model', () => { model.removeBreakpoints(model.getBreakpoints().filter(bp => bp.uri.toString() === modelUri1.toString())); assert.equal(model.getBreakpoints().length, 3); + + model.unverifyBreakpoints(); + model.getBreakpoints().forEach(bp => assert.equal(bp.verified, false)); }); test('breakpoints conditions', () => { @@ -88,6 +92,24 @@ suite('Debug - Model', () => { assert.equal(model.getBreakpoints().length, 0); }); + test('function brekapoints', () => { + model.addFunctionBreakpoint('foo', '1'); + model.addFunctionBreakpoint('bar', '2'); + model.updateFunctionBreakpoints({ + '1': { name: 'fooUpdated', verified: true, hitCondition: '5' }, + '2': { name: 'barUpdated', verified: false } + }); + const functionBps = model.getFunctionBreakpoints(); + assert.equal(functionBps[0].name, 'fooUpdated'); + assert.equal(functionBps[0].verified, true); + assert.equal(functionBps[0].hitCondition, '5'); + assert.equal(functionBps[1].name, 'barUpdated'); + assert.equal(functionBps[1].verified, false); + + model.removeFunctionBreakpoints(); + assert.equal(model.getFunctionBreakpoints().length, 0); + }); + // Threads test('threads simple', () => { diff --git a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts index 175ea3e68f6e..fc3295626000 100644 --- a/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts +++ b/src/vs/workbench/parts/localizations/electron-browser/localizations.contribution.ts @@ -120,7 +120,7 @@ export class LocalizationWorkbenchContribution extends Disposable implements IWo .then(coreLanguages => { if (coreLanguages.some(c => c.toLowerCase() === language)) { const extensionIdPrefix = language === 'zh-cn' ? 'zh-hans' : language === 'zh-tw' ? 'zh-hant' : language; - const extensionId = product.quality !== 'insider' ? `MS-CEINTL.vscode-insiders-language-pack-${extensionIdPrefix}` : `MS-CEINTL.vscode-language-pack-${extensionIdPrefix}`; + const extensionId = product.quality === 'insider' ? `MS-CEINTL.vscode-insiders-language-pack-${extensionIdPrefix}` : `MS-CEINTL.vscode-language-pack-${extensionIdPrefix}`; return this.galleryService.query({ names: [extensionId], pageSize: 1 }) .then(result => result.total === 1 ? result.firstPage[0] : null); } diff --git a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md index d58daa2668d1..9f5fcd088271 100644 --- a/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md +++ b/src/vs/workbench/parts/welcome/walkThrough/electron-browser/editor/vs_code_editor_walkthrough.md @@ -118,7 +118,7 @@ console.log(`This is the manufacturer [${cars[i]}])`); ### Code Folding -In a large file it can often be useful to collapse sections of code to increase readability. To do this you can simply press kb(editor.fold) to fold the code, press kb(editor.unfold) to unfold. Folding can also be done with the +/- icons in the left gutter. To fold all sections use kb(editor.foldAll) or to unfold all use kb(editor.unfoldAll). +In a large file it can often be useful to collapse sections of code to increase readability. To do this, you can simply press kb(editor.fold) to fold or press kb(editor.unfold) to unfold the ranges at the current cursor position. Folding can also be done with the +/- icons in the left gutter. To fold all sections use kb(editor.foldAll) or to unfold all use kb(editor.unfoldAll). ```html
diff --git a/src/vs/workbench/services/untitled/common/untitledEditorService.ts b/src/vs/workbench/services/untitled/common/untitledEditorService.ts index fdccdb3a9e9a..b667bea963a2 100644 --- a/src/vs/workbench/services/untitled/common/untitledEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledEditorService.ts @@ -23,6 +23,7 @@ export interface IModelLoadOrCreateOptions { modeId?: string; initialValue?: string; encoding?: string; + useResourcePath?: boolean; } export interface IUntitledEditorService { @@ -193,16 +194,17 @@ export class UntitledEditorService implements IUntitledEditorService { } public loadOrCreate(options: IModelLoadOrCreateOptions = Object.create(null)): TPromise { - return this.createOrGet(options.resource, options.modeId, options.initialValue, options.encoding).resolve(); + return this.createOrGet(options.resource, options.modeId, options.initialValue, options.encoding, options.useResourcePath).resolve(); } - public createOrGet(resource?: URI, modeId?: string, initialValue?: string, encoding?: string): UntitledEditorInput { + public createOrGet(resource?: URI, modeId?: string, initialValue?: string, encoding?: string, hasAssociatedFilePath: boolean = false): UntitledEditorInput { - // Massage resource if it comes with a file:// scheme - let hasAssociatedFilePath = false; if (resource) { - hasAssociatedFilePath = (resource.scheme === Schemas.file); - resource = resource.with({ scheme: Schemas.untitled }); // ensure we have the right scheme + // Massage resource if it comes with a file:// scheme + if (resource.scheme === Schemas.file) { + hasAssociatedFilePath = true; + resource = resource.with({ scheme: Schemas.untitled }); // ensure we have the right scheme + } if (hasAssociatedFilePath) { this.mapResourceToAssociatedFilePath.set(resource, true); // remember for future lookups diff --git a/test/smoke/README.md b/test/smoke/README.md index 349fc63c63be..b3a137953d41 100644 --- a/test/smoke/README.md +++ b/test/smoke/README.md @@ -1,22 +1,39 @@ # VS Code Smoke Test -## How to run +### Run ``` # Dev yarn smoketest # Build -yarn smoketest --build "path/to/code" +yarn smoketest --build PATH_TO_BUILD ``` -Screenshots can be captured when tests fail. In order to get them, you need to use the argument `--screenshots SCREENSHOT_DIR`. +### Run for a release -## How to debug issues +You must always run the smoketest version which matches the release you are testing. So, if you want to run the smoketest for a release build (eg `release/1.22`), you need that version of the smoke tests too: -You can use a `--verbose` flag to log all the low level driver calls make to Code. +``` +git checkout release/1.22 +yarn +yarn smoketest --build PATH_TO_RELEASE_BUILD +``` -You can also use any mocha argument. For example, use `-f Git` to filter all tests except the `Git` tests. +### Debug + +- `--verbose` logs all the low level driver calls made to Code; +- `-f PATTERN` filters the tests to be run. You can also use pretty much any mocha argument; +- `--screenshots SCREENSHOT_DIR` captures screenshots when tests fail. + +### Develop + +Start a watch task in `test/smoke`: + +``` +cd test/smoke +yarn watch +``` ## Pitfalls diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 84bb2d539684..4162d6419dc7 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -224,7 +224,12 @@ export class Code { async waitForTextContent(selector: string, textContent?: string, accept?: (result: string) => boolean): Promise { const windowId = await this.getActiveWindowId(); accept = accept || (result => textContent !== void 0 ? textContent === result : !!result); - return await poll(() => this.driver.getElements(windowId, selector).then(els => els[0].textContent), s => accept!(typeof s === 'string' ? s : ''), `get text content '${selector}'`); + + return await poll( + () => this.driver.getElements(windowId, selector).then(els => els.length > 0 ? Promise.resolve(els[0].textContent) : Promise.reject(new Error('Element not found for textContent'))), + s => accept!(typeof s === 'string' ? s : ''), + `get text content '${selector}'` + ); } async waitAndClick(selector: string, xoffset?: number, yoffset?: number): Promise {