diff --git a/modules/syntax/src/main/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizer.kt b/modules/syntax/src/main/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizer.kt index 50f8512..2a2f010 100644 --- a/modules/syntax/src/main/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizer.kt +++ b/modules/syntax/src/main/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizer.kt @@ -16,7 +16,8 @@ package com.progmasoft.xide.syntax * - a comment whose text starts with `|` or `!` is a documentation comment; * - `[[` and `[=[` start a raw string with the same long-bracket rule, in which nothing is an escape; * - a quoted string may continue over line breaks and has backslash escapes; - * - `'` separates digit groups inside a number and otherwise starts a character literal. + * - `'` separates digit groups inside a number and otherwise starts a character literal; + * - `::` is one sign, the method reference of `Type::Method`, and not two colons. */ object VisualXSharpTokenizer : Tokenizer { /** The reserved words of the language, as the compiler's lexer lists them. */ @@ -32,7 +33,7 @@ object VisualXSharpTokenizer : Tokenizer { private val operators: List = listOf( "...", "<<=", ">>=", "**=", "//=", "??=", - "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "??", "?:", "==", "\\=", "<=", ">=", "&&", "||", "//", "->", + "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "??", "?:", "::", "==", "\\=", "<=", ">=", "&&", "||", "//", "->", "**", "++", "=", "+", "-", "*", "/", "%", "&", "|", "^", "<", ">", "!", "?", "\\", ) diff --git a/modules/syntax/src/test/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizerTest.kt b/modules/syntax/src/test/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizerTest.kt index 0d9ec51..90898ba 100644 --- a/modules/syntax/src/test/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizerTest.kt +++ b/modules/syntax/src/test/kotlin/com/progmasoft/xide/syntax/VisualXSharpTokenizerTest.kt @@ -126,6 +126,30 @@ class VisualXSharpTokenizerTest { tokenizer.assertPieces("!mask", O to "!", I to "mask") } + @Test + fun aMethodReferenceIsOneSignBetweenTwoNames() { + tokenizer.assertPieces( + "auto next = Counter::Next;", + K to "auto", I to "next", O to "=", I to "Counter", O to "::", I to "Next", P to ";", + ) + tokenizer.assertPieces( + "Apply(Demo.Counter::Next)", + I to "Apply", P to "(", I to "Demo", P to ".", I to "Counter", O to "::", I to "Next", P to ")", + ) + // One colon is still the punctuation of a conditional. + tokenizer.assertPieces("a ? b : c", I to "a", O to "?", I to "b", P to ":", I to "c") + tokenizer.assertPieces("a :: : b", I to "a", O to "::", P to ":", I to "b") + } + + @Test + fun aConditionalSelectsStrings() { + tokenizer.assertPieces( + "String kind = count > 0 ? \"some\" : \"none\";", + I to "String", I to "kind", O to "=", I to "count", O to ">", N to "0", O to "?", S to "\"some\"", + P to ":", S to "\"none\"", P to ";", + ) + } + @Test fun everyCompilerKeywordIsAKeyword() { for (keyword in VisualXSharpTokenizer.keywords) {