/*! `csharp` grammar compiled for Highlight.js 11.11.1 */
(function() {
var hljsGrammar = (function() {
'use strict';
const symbolState = {
memberNames: new Set()
};
const normalizeIdentifier = value => value.startsWith('@') ? value.slice(1) : value;
/*
Language: C#
Author: Jason Diamond <jason@diamond.name>
Contributor: Nicolas LLOBERA <nllobera@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, David Pine <david.pine@microsoft.com>
Website: https://docs.microsoft.com/dotnet/csharp/
Category: common
*/
/** @type LanguageFn */
function csharp(hljs) {
const BUILT_IN_KEYWORDS = [
'bool',
'byte',
'char',
'decimal',
'delegate',
'double',
'dynamic',
'enum',
'float',
'int',
'long',
'nint',
'nuint',
'object',
'sbyte',
'short',
'string',
'ulong',
'uint',
'ushort'
];
const FUNCTION_MODIFIERS = [
'public',
'private',
'protected',
'static',
'internal',
'protected',
'abstract',
'async',
'extern',
'override',
'unsafe',
'virtual',
'new',
'sealed',
'partial'
];
const LITERAL_KEYWORDS = [
'default',
'false',
'null',
'true'
];
const CONTROL_KEYWORDS = [
'break', 'case', 'catch', 'continue', 'do', 'else', 'finally', 'fixed', 'for', 'foreach', 'goto', 'if', 'return', 'switch', 'throw', 'try', 'while', 'yield', 'await'
];
const NORMAL_KEYWORDS = [
'abstract',
'as',
'base',
'break',
'case',
'catch',
'checked',
'class',
'const',
'continue',
'do',
'else',
'event',
'explicit',
'extern',
'finally',
'fixed',
'for',
'foreach',
'goto',
'if',
'implicit',
'in',
'interface',
'internal',
'is',
'lock',
'namespace',
'new',
'operator',
'out',
'override',
'params',
'private',
'protected',
'public',
'readonly',
'record',
'ref',
'return',
'scoped',
'sealed',
'sizeof',
'stackalloc',
'static',
'struct',
'switch',
'this',
'throw',
'try',
'typeof',
'unchecked',
'unsafe',
'using',
'virtual',
'void',
'volatile',
'while'
].filter(k => !CONTROL_KEYWORDS.includes(k));
const CONTEXTUAL_KEYWORDS = [
'add',
'alias',
'and',
'ascending',
'args',
'async',
'await',
'by',
'descending',
'dynamic',
'equals',
'file',
'from',
'get',
'global',
'group',
'init',
'into',
'join',
'let',
'nameof',
'not',
'notnull',
'on',
'or',
'orderby',
'partial',
'record',
'remove',
'required',
'scoped',
'select',
'set',
'unmanaged',
'value|0',
'var',
'when',
'where',
'with',
'yield'
].filter(k => !CONTROL_KEYWORDS.includes(k));
const SYSTEM_CLASSES = [
'Boolean', 'Byte', 'Char', 'DateTime', 'DateTimeOffset', 'Decimal', 'Double', 'Guid', 'Int16', 'Int32', 'Int64', 'Object', 'SByte', 'Single', 'String', 'TimeSpan', 'UInt16', 'UInt32', 'UInt64', 'HttpListener', 'Console', 'Math', 'Environment', 'Convert', 'BitConverter', 'Random', 'Action', 'Func', 'Predicate', 'List', 'Dictionary', 'HashSet', 'Queue', 'Stack', 'LinkedList', 'Task', 'Process', 'Thread', 'File', 'Directory', 'Path', 'Stream', 'FileStream', 'MemoryStream', 'StreamReader', 'StreamWriter', 'Exception', 'StringBuilder', 'HttpClient', 'JsonConvert', 'Uri', 'CancellationToken', 'CultureInfo', 'Encoding', 'Regex', 'AppDomain', 'GC', 'UnhandledExceptionEventArgs', 'Page', 'EventArgs', 'Trace', 'Debugger', 'Application', 'App',
'QueryableJsonNode', 'LANDeviceDetector', 'TestClass', 'XFEChatGPT', 'MemorableXFEChatGPT', 'CyberCommServer', 'CyberCommClient', 'XCCNetWork', 'XFEDownloader', 'CyberCommServerEventArgs', 'CyberCommClientEventArgs',
'StaticMemoryManager', 'DynamicMemoryManager', 'UpdatableMemoryManager', 'MemoryItem', 'MemoryValue', 'MemoryManager', 'MemoryItemBuilder',
'XFEConsole', 'XFELog',
'InputSimulator',
'PageManager', 'AppThemeHelper', 'AppShellPage', 'MainPage', 'TestPage', 'ServiceManager',
'XFEProfile', 'SystemProfile', 'ProfileList', 'ProfileDictionary',
'XFEServerBuilder', 'XFEServerCoreBuilder', 'XFEClientRequesterBuilder', 'UserProfile', 'DataProfile', 'XFEDataTableManagerBuilder',
'Upgrader',
];
const SYSTEM_INTERFACES = [
'IEnumerable', 'IQueryable', 'IDisposable', 'IAsyncDisposable', 'ICloneable', 'IComparable', 'IEquatable', 'IFormatProvider', 'IFormattable', 'IServiceProvider', 'IOrderedEnumerable', 'IAsyncEnumerable', 'IReadOnlyList', 'IReadOnlyCollection', 'IReadOnlyDictionary', 'IList', 'ICollection', 'IDictionary', 'ISet', 'INotifyPropertyChanged', 'IObservable', 'IObserver', 'IActionResult', 'IAsync',
'IUserFaceInfo',
'IMessageService', 'INavigationViewService', 'ILoadingService',
];
const SYSTEM_ENUMS = [
'ConsoleColor', 'ConsoleKey', 'DateTimeKind', 'DayOfWeek', 'FileAccess', 'FileMode', 'FileShare', 'FileAttributes', 'StringSplitOptions', 'StringComparison', 'TaskStatus', 'TaskCreationOptions', 'TaskContinuationOptions', 'PlatformID', 'Point', 'ScreenPosition', 'HttpStatusCode',
'GenerateState',
'UserRole',
'MouseButton',
'InfoBarSeverity', 'ElementTheme',
];
const KEYWORDS = {
keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS),
built_in: BUILT_IN_KEYWORDS,
literal: LITERAL_KEYWORDS,
type: SYSTEM_CLASSES,
interface: SYSTEM_INTERFACES,
enum: SYSTEM_ENUMS
};
const IDENTIFIER_START_RE = '(?:[A-Za-z_]|[\\u0080-\\uFFFF])';
const IDENTIFIER_PART_RE = '(?:[A-Za-z0-9_]|[\\u0080-\\uFFFF])';
const IDENTIFIER_BOUNDARY_RE = '(?<!' + IDENTIFIER_PART_RE + ')';
const IDENTIFIER_RE = '@?' + IDENTIFIER_START_RE + IDENTIFIER_PART_RE + '*';
const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: IDENTIFIER_RE + '(\\.' + IDENTIFIER_RE + ')*' });
const NUMBERS = {
className: 'number',
variants: [
{ begin: '\\b(0b[01\']+)' },
{ begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B|d|D|m|M)' },
{ begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
],
relevance: 0
};
const RAW_STRING = {
className: 'string',
begin: /"""("*)(?!")(.|\n)*?"""\1/,
relevance: 1
};
const VERBATIM_STRING = {
className: 'string',
begin: '@"',
end: '"',
contains: [{ begin: '""' }]
};
const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { illegal: /\n/ });
const SUBST = {
className: 'subst',
begin: /\{/,
end: /\}/,
keywords: KEYWORDS
};
const SUBST_NO_LF = hljs.inherit(SUBST, { illegal: /\n/ });
const INTERPOLATED_STRING = {
className: 'string',
begin: /\$"/,
end: '"',
illegal: /\n/,
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
hljs.BACKSLASH_ESCAPE,
SUBST_NO_LF
]
};
const INTERPOLATED_VERBATIM_STRING = {
className: 'string',
begin: /\$@"/,
end: '"',
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST
]
};
const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {
illegal: /\n/,
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST_NO_LF
]
});
SUBST.contains = [
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBERS,
hljs.C_BLOCK_COMMENT_MODE
];
SUBST_NO_LF.contains = [
INTERPOLATED_VERBATIM_STRING_NO_LF,
INTERPOLATED_STRING,
VERBATIM_STRING_NO_LF,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBERS,
hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { illegal: /\n/ })
];
const STRING = {
variants: [
RAW_STRING,
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
]
};
const ALL_KEYWORD_NAMES = Array.from(new Set(
NORMAL_KEYWORDS
.concat(CONTEXTUAL_KEYWORDS, CONTROL_KEYWORDS, LITERAL_KEYWORDS, BUILT_IN_KEYWORDS)
.map(keyword => keyword.replace('|0', ''))
));
const KEYWORD_SOURCE = ALL_KEYWORD_NAMES.join('|');
const TYPE_KEYWORD_GUARD_RE = '(?!(?:' + KEYWORD_SOURCE + ')\\b)';
const PREDEFINED_TYPE_NAMES = BUILT_IN_KEYWORDS
.filter(keyword => keyword !== 'delegate' && keyword !== 'enum')
.concat('void');
const PREDEFINED_TYPE_RE = '(?:' + PREDEFINED_TYPE_NAMES.join('|') + ')';
const QUALIFIED_IDENTIFIER_RE = '(?:(?:global|' + IDENTIFIER_RE + ')\\s*::\\s*)?'
+ IDENTIFIER_RE
+ '(?:\\s*\\.\\s*' + IDENTIFIER_RE + ')*';
const TYPE_SUFFIX_RE = '(?:\\s*\\?)?(?:\\s*\\[\\s*(?:,\\s*)*\\])*(?:\\s*\\*)*';
const buildGenericType = (namePattern, argumentPattern) => namePattern
+ '(?:\\s*<\\s*' + argumentPattern + '(?:\\s*,\\s*' + argumentPattern + ')*\\s*>)?'
+ TYPE_SUFFIX_RE;
const SIMPLE_TYPE_RE = QUALIFIED_IDENTIFIER_RE + TYPE_SUFFIX_RE;
const ONE_LEVEL_TYPE_RE = buildGenericType(QUALIFIED_IDENTIFIER_RE, SIMPLE_TYPE_RE);
const TYPE_REFERENCE_BODY_RE = buildGenericType(QUALIFIED_IDENTIFIER_RE, ONE_LEVEL_TYPE_RE);
const TYPE_REFERENCE_RE = IDENTIFIER_BOUNDARY_RE
+ '(?:(?=global\\s*::)|' + TYPE_KEYWORD_GUARD_RE + ')'
+ TYPE_REFERENCE_BODY_RE;
const INTERFACE_REFERENCE_RE = IDENTIFIER_BOUNDARY_RE
+ buildGenericType('I[A-Z][A-Za-z0-9_]*', ONE_LEVEL_TYPE_RE);
const DECLARATION_FOLLOW_RE = '(?=\\s+' + IDENTIFIER_RE
+ '\\s*(?:=|;|,|\\)|\\{|\\[|=>|\\bin\\b|\\())';
const PREDEFINED_TYPE_MODE = {
className: 'built_in',
begin: new RegExp('\\b' + PREDEFINED_TYPE_RE + '\\b'),
relevance: 0
};
const INTERFACE_NAME_MODE = {
className: 'interface',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + 'I[A-Z][A-Za-z0-9_]*'),
relevance: 0
};
const TYPE_NAME_MODE = {
className: 'type',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + TYPE_KEYWORD_GUARD_RE + IDENTIFIER_RE),
relevance: 0
};
const NAMED_INTERFACE_OR_TYPE = [INTERFACE_NAME_MODE, TYPE_NAME_MODE];
const GENERIC_MODIFIER = {
begin: /</,
end: />/,
relevance: 0,
contains: [
{ beginKeywords: 'in out', relevance: 0 },
PREDEFINED_TYPE_MODE,
INTERFACE_NAME_MODE,
TYPE_NAME_MODE,
'self'
]
};
const TYPE_IDENT_RE = TYPE_REFERENCE_BODY_RE;
const AT_IDENTIFIER = {
// prevents expressions like `@class` from incorrect flagging
// `class` as a keyword
begin: '@' + hljs.IDENT_RE,
relevance: 0
};
const CONSTRUCTOR_MODIFIERS = [
'public',
'private',
'protected',
'static',
'internal',
'extern',
'unsafe'
];
const CONSTRUCTOR = {
className: 'constructor',
begin: '\\b(' + CONSTRUCTOR_MODIFIERS.join('|') + ')\\s+' + IDENTIFIER_RE + '\\s*\\(',
returnBegin: true,
end: /\(/,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
{
beginKeywords: CONSTRUCTOR_MODIFIERS.join(" "),
relevance: 0
},
{
className: 'title',
begin: IDENTIFIER_RE,
relevance: 0
}
]
};
// Type names can legally use any casing. Restrict the broad rule to
// declaration syntax so expressions and ordinary variables are not
// mistaken for types.
const INTERFACE_IN_DECLARATION = {
begin: new RegExp(INTERFACE_REFERENCE_RE + DECLARATION_FOLLOW_RE),
className: 'interface',
relevance: 0
};
const TYPE_IN_DECLARATION = {
begin: new RegExp(TYPE_REFERENCE_RE + DECLARATION_FOLLOW_RE),
className: 'type',
relevance: 0
};
const rememberMemberName = match => {
symbolState.memberNames.add(normalizeIdentifier(match[0]));
};
const PROPERTY_NAME = {
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + IDENTIFIER_RE + '(?=\\s*(?:\\{|=>))'),
relevance: 0,
'on:begin': rememberMemberName
};
const PROPERTY_DECLARATION = {
begin: new RegExp(TYPE_REFERENCE_RE + '\\s+' + IDENTIFIER_RE + '\\s*(?=\\{|=>)'),
returnBegin: true,
end: /\{|=>/,
excludeEnd: true,
relevance: 0,
contains: [
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
PROPERTY_NAME
]
};
const FIELD_NAME = {
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + IDENTIFIER_RE + '(?=\\s*(?:=|;))'),
relevance: 0,
'on:begin': rememberMemberName
};
const FIELD_MODIFIERS_RE = '(?:public|private|protected|internal|static|readonly|volatile|new|unsafe|required)';
const FIELD_DECLARATION = {
begin: new RegExp('\\b(?:' + FIELD_MODIFIERS_RE + '\\s+)+' + TYPE_REFERENCE_RE
+ '\\s+' + IDENTIFIER_RE + '\\s*(?==|;)'),
returnBegin: true,
end: /=|;/,
excludeEnd: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
FIELD_NAME
]
};
const DECLARED_MEMBER_REFERENCE = {
// C# members conventionally begin with PascalCase; private fields
// commonly use an underscore. Keeping this mode narrower prevents
// ordinary camelCase locals from being consumed before VARIABLE.
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '@?(?:[A-Z_]|[\\u0080-\\uFFFF])'
+ IDENTIFIER_PART_RE + '*'),
relevance: 0,
'on:begin': (match, response) => {
if (!symbolState.memberNames.has(normalizeIdentifier(match[0]))) {
response.ignoreMatch();
}
}
};
const CONTROL_FLOW = {
className: 'csharp-keyword',
match: new RegExp('\\b(' + CONTROL_KEYWORDS.join('|') + ')\\b'),
relevance: 0
};
const FUNCTION_CALL_EXCLUSIONS = Array.from(new Set(
ALL_KEYWORD_NAMES.concat('checked', 'default', 'nameof', 'sizeof', 'typeof', 'unchecked')
)).join('|');
const FUNCTION_CALL = {
className: 'function',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '(?!(?:' + FUNCTION_CALL_EXCLUSIONS + ')\\b)'
+ IDENTIFIER_RE + '(?=\\s*(?:<[^=<>]*(?:<[^=<>]*>[^=<>]*)*>\\s*)?\\()'),
returnBegin: true,
end: /\(/,
excludeEnd: true,
relevance: 0,
contains: [
{
className: 'title',
begin: new RegExp(IDENTIFIER_RE),
relevance: 0
},
GENERIC_MODIFIER
]
};
const NEW_PREDEFINED_TYPE = {
match: [
/\bnew\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*(?:\\(|\\[|\\{))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const INSTANTIATION = {
match: [
/\bnew\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*(?:\\(|\\[|\\{))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const TYPE_OPERATOR_PREDEFINED = {
match: [
/\b(?:default|sizeof|typeof)\b/,
/\s*\(\s*/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*\\))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const TYPE_OPERATOR_UNBOUND_GENERIC = {
match: [
/\btypeof\b/,
/\s*\(\s*/,
new RegExp(IDENTIFIER_BOUNDARY_RE + QUALIFIED_IDENTIFIER_RE
+ '\\s*<\\s*(?:,\\s*)*>\\s*(?=\\))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const TYPE_OPERATOR = {
match: [
/\b(?:default|sizeof|typeof)\b/,
/\s*\(\s*/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*\\))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const AS_IS_PREDEFINED_TYPE = {
match: [
/\b(?:as|is)\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*(?:[;,\\)\\]}]|' + IDENTIFIER_RE + '\\b))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const AS_IS_TYPE = {
match: [
/\b(?:as|is)\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*(?:[;,\\)\\]}]|' + IDENTIFIER_RE + '\\b))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const CAST_PREDEFINED_TYPE = {
match: [
/\(\s*/,
new RegExp(PREDEFINED_TYPE_RE),
/\s*\)(?=\s*(?:@?[A-Za-z_]|\d|["'(]))/
],
scope: { 2: 'built_in' },
relevance: 0
};
const CAST_TYPE = {
match: [
/\(\s*/,
new RegExp(TYPE_REFERENCE_RE),
/\s*\)(?=\s*(?:@?[A-Za-z_]|\d|["'(]))/
],
scope: { 2: 'type' },
relevance: 0
};
const PASCAL_STATIC_TYPE = {
className: 'type',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '[A-Z][A-Za-z0-9_]*(?=\\s*(?:\\.|::))'),
relevance: 0
};
const MEMBER_ACCESS = {
begin: new RegExp('\\.\\s*' + IDENTIFIER_RE + '(?!' + IDENTIFIER_PART_RE + ')'
+ '(?!\\s*(?:<[^=<>]*(?:<[^=<>]*>[^=<>]*)*>\\s*)?\\()'),
relevance: 0
};
const ATTRIBUTE_TARGET = {
className: 'meta',
begin: /\b(?:assembly|module|field|event|method|param|property|return|type|typevar)\s*:/,
relevance: 0
};
const ATTRIBUTE_NAME_RE = '(?:(?:global\\s*::\\s*)?'
+ '(?:' + IDENTIFIER_RE + '\\s*\\.\\s*)*)'
+ '@?[A-Z_][A-Za-z0-9_]*'
+ '(?:\\s*<[^<>\\r\\n]*(?:<[^<>\\r\\n]*>[^<>\\r\\n]*)*>)?';
const ATTRIBUTE_NAME = {
className: 'meta',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + ATTRIBUTE_NAME_RE + '(?=\\s*(?:\\(|,|\\]))'),
relevance: 0
};
const ATTRIBUTE_NESTED_BRACKETS = {
begin: /\[/,
end: /\]/,
relevance: 0,
contains: [STRING, NUMBERS, hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE]
};
const ATTRIBUTE_SECTION = {
begin: new RegExp('\\[(?=\\s*(?:(?:assembly|module|field|event|method|param|property|return|type|typevar)'
+ '\\s*:\\s*)?' + ATTRIBUTE_NAME_RE + ')'),
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
ATTRIBUTE_TARGET,
ATTRIBUTE_NAME,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
ATTRIBUTE_NESTED_BRACKETS
]
};
const ATTRIBUTE_ANY_NAME_RE = QUALIFIED_IDENTIFIER_RE
+ '(?:\\s*<[^<>\\r\\n]*(?:<[^<>\\r\\n]*>[^<>\\r\\n]*)*>)?';
const ATTRIBUTE_TARGET_RE = '(?:assembly|module|field|event|method|param|property|return|type|typevar)\\s*:';
const ATTRIBUTE_ANY_NAME_WITH_END_RE = ATTRIBUTE_ANY_NAME_RE + '(?=\\s*(?:\\(|,|\\]))';
const ATTRIBUTE_ANY_CONTENTS = [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
ATTRIBUTE_NAME,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
ATTRIBUTE_NESTED_BRACKETS
];
const LINE_ATTRIBUTE_SECTION = {
begin: [
/^\s*\[/,
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: { 3: 'meta' },
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const LINE_TARGET_ATTRIBUTE_SECTION = {
begin: [
/^\s*\[/,
/\s*/,
new RegExp(ATTRIBUTE_TARGET_RE),
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: {
3: 'meta',
5: 'meta'
},
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const PARAMETER_ATTRIBUTE_SECTION = {
begin: [
/\[/,
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: { 3: 'meta' },
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const PARAMETER_TARGET_ATTRIBUTE_SECTION = {
begin: [
/\[/,
/\s*/,
new RegExp(ATTRIBUTE_TARGET_RE),
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: {
3: 'meta',
5: 'meta'
},
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const DECLARATION_VARIABLE = {
className: 'variable',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '(?!(?:' + KEYWORD_SOURCE + ')\\b)' + IDENTIFIER_RE),
relevance: 0
};
const DECLARATION_PARAMETER_LIST = {
begin: /\(/,
end: /\)/,
relevance: 0,
keywords: KEYWORDS,
contains: [
PARAMETER_TARGET_ATTRIBUTE_SECTION,
PARAMETER_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
FUNCTION_CALL,
DECLARATION_VARIABLE
]
};
const DECLARATION_CONSTRAINT_KEYWORDS = {
beginKeywords: 'where class struct notnull unmanaged new',
relevance: 0
};
const TYPE_DECLARATION_CONTENTS = [
DECLARATION_PARAMETER_LIST,
GENERIC_MODIFIER,
DECLARATION_CONSTRAINT_KEYWORDS,
PREDEFINED_TYPE_MODE,
INTERFACE_NAME_MODE,
TYPE_NAME_MODE,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
];
const CLASS_OR_STRUCT_DECLARATION = {
begin: [
/\b(?:class|struct)\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const INTERFACE_DECLARATION = {
begin: [
/\binterface\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'interface'
},
end: /[{;]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const RECORD_KIND_DECLARATION = {
begin: [
/\brecord\b/,
/\s+/,
/(?:class|struct)/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'keyword',
5: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const RECORD_DECLARATION = {
begin: [
/\brecord\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const ENUM_DECLARATION = {
begin: [
/\benum\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'enum'
},
end: /[{;]/,
relevance: 0,
keywords: KEYWORDS,
contains: [
PREDEFINED_TYPE_MODE,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
};
const DELEGATE_PREFIX_RE = '\\b(?:(?:public|private|protected|internal|static|unsafe|new)\\s+)*delegate\\b';
const DELEGATE_PREDEFINED_DECLARATION = {
begin: [
new RegExp(DELEGATE_PREFIX_RE),
/\s+/,
new RegExp(PREDEFINED_TYPE_RE),
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'built_in',
5: 'type'
},
end: /;/,
relevance: 0,
keywords: KEYWORDS,
contains: [GENERIC_MODIFIER, DECLARATION_PARAMETER_LIST]
};
const DELEGATE_DECLARATION = {
begin: [
new RegExp(DELEGATE_PREFIX_RE),
/\s+/,
new RegExp(TYPE_REFERENCE_RE),
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type',
5: 'type'
},
end: /;/,
relevance: 0,
keywords: KEYWORDS,
contains: [GENERIC_MODIFIER, DECLARATION_PARAMETER_LIST]
};
const CONVERSION_OPERATOR_PREDEFINED_TYPE = {
match: [
/\b(?:explicit|implicit)\b/,
/\s+/,
/operator\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE)
],
scope: {
1: 'keyword',
3: 'keyword',
5: 'built_in'
},
relevance: 0
};
const CONVERSION_OPERATOR_TYPE = {
match: [
/\b(?:explicit|implicit)\b/,
/\s+/,
/operator\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE)
],
scope: {
1: 'keyword',
3: 'keyword',
5: 'type'
},
relevance: 0
};
const OPERATOR_PREDEFINED_RETURN_TYPE = {
match: [
new RegExp(IDENTIFIER_BOUNDARY_RE + PREDEFINED_TYPE_RE),
/\s+/,
/operator\b/
],
scope: {
1: 'built_in',
3: 'keyword'
},
relevance: 0
};
const OPERATOR_RETURN_TYPE = {
match: [
new RegExp(TYPE_REFERENCE_RE),
/\s+/,
/operator\b/
],
scope: {
1: 'type',
3: 'keyword'
},
relevance: 0
};
const USING_STATIC_TYPE = {
match: [
/\busing\s+static\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const USING_ALIAS_TYPE = {
match: [
/\busing\b/,
/\s+/,
new RegExp(IDENTIFIER_RE),
/\s*=\s*/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'type',
5: 'type'
},
relevance: 0
};
const USING_NAMESPACE = {
match: [
/\busing\b/,
/\s+/,
new RegExp(QUALIFIED_IDENTIFIER_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'namespace'
},
relevance: 0
};
const NAMESPACE_NAME = {
className: 'namespace',
begin: new RegExp(QUALIFIED_IDENTIFIER_RE),
relevance: 0
};
return {
name: 'C#',
aliases: [
'cs',
'c#'
],
keywords: KEYWORDS,
contains: [
hljs.COMMENT(
'///',
'$',
{
returnBegin: true,
contains: [
{
className: 'doctag',
variants: [
{
begin: '///',
relevance: 0
},
{ begin: '<!--|-->' },
{
begin: '</?',
end: '>'
}
]
}
]
}
),
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
LINE_TARGET_ATTRIBUTE_SECTION,
LINE_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
{
className: 'meta',
begin: '#',
end: '$',
keywords: { keyword: 'if else elif endif define undef warning error line region endregion pragma checksum nullable' }
},
STRING,
NUMBERS,
CONTROL_FLOW,
USING_STATIC_TYPE,
USING_ALIAS_TYPE,
USING_NAMESPACE,
CLASS_OR_STRUCT_DECLARATION,
INTERFACE_DECLARATION,
RECORD_KIND_DECLARATION,
RECORD_DECLARATION,
ENUM_DECLARATION,
DELEGATE_PREDEFINED_DECLARATION,
DELEGATE_DECLARATION,
CONSTRUCTOR,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
AS_IS_PREDEFINED_TYPE,
AS_IS_TYPE,
CAST_PREDEFINED_TYPE,
CAST_TYPE,
CONVERSION_OPERATOR_PREDEFINED_TYPE,
CONVERSION_OPERATOR_TYPE,
OPERATOR_PREDEFINED_RETURN_TYPE,
OPERATOR_RETURN_TYPE,
PROPERTY_DECLARATION,
FIELD_DECLARATION,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
DECLARED_MEMBER_REFERENCE,
FUNCTION_CALL,
PASCAL_STATIC_TYPE,
{
beginKeywords: 'namespace',
relevance: 0,
end: /[{;=]/,
illegal: /[^\s:]/,
contains: [
NAMESPACE_NAME,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
{
// Expression keywords prevent 'keyword Name(...)' from being
// recognized as a function definition
beginKeywords: 'new return throw await else checked default nameof sizeof typeof unchecked',
relevance: 0
},
{
className: 'function',
begin: '(' + TYPE_IDENT_RE + '\\s+)+' + IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
end: /\s*[{;=]/,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
// prevents these from being highlighted `title`
{
beginKeywords: FUNCTION_MODIFIERS.join(" "),
relevance: 0
},
{
begin: IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
contains: [
hljs.TITLE_MODE,
GENERIC_MODIFIER
],
relevance: 0
},
...NAMED_INTERFACE_OR_TYPE,
{ match: /\(\)/ },
{
className: 'params',
begin: /\(/,
end: /\)/,
excludeBegin: true,
excludeEnd: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
PARAMETER_TARGET_ATTRIBUTE_SECTION,
PARAMETER_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
STRING,
NUMBERS,
hljs.C_BLOCK_COMMENT_MODE,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
{
className: 'variable',
begin: new RegExp('\\b(?!(?:' + KEYWORD_SOURCE + ')\\b)[a-z_][A-Za-z0-9_]*\\b'),
relevance: 0
}
]
},
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
MEMBER_ACCESS,
{
begin: '\\.' + IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
end: /[\(]/,
excludeEnd: true,
relevance: 0,
contains: [
{
begin: /\./
},
{
className: 'dotfunction',
begin: hljs.IDENT_RE,
relevance: 0
},
GENERIC_MODIFIER
]
},
{
className: 'variable',
begin: new RegExp('\\b(?!(?:' + KEYWORD_SOURCE + ')\\b)[a-z_][A-Za-z0-9_]*\\b'),
relevance: 0
},
AT_IDENTIFIER
]
};
}
csharp.resetSymbolState = () => symbolState.memberNames.clear();
return csharp;
})();
hljs.registerLanguage('csharp', hljsGrammar);
if (typeof hljs.addPlugin === 'function') {
hljs.addPlugin({
'before:highlight': context => {
if (context.language === 'csharp' || context.language === 'cs' || context.language === 'c#') {
hljsGrammar.resetSymbolState();
}
}
});
}
})();
/*! `csharp` grammar compiled for Highlight.js 11.11.1 */
(function() {
var hljsGrammar = (function() {
'use strict';
const symbolState = {
memberNames: new Set()
};
const normalizeIdentifier = value => value.startsWith('@') ? value.slice(1) : value;
/*
Language: C#
Author: Jason Diamond <jason@diamond.name>
Contributor: Nicolas LLOBERA <nllobera@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, David Pine <david.pine@microsoft.com>
Website: https://docs.microsoft.com/dotnet/csharp/
Category: common
*/
/** @type LanguageFn */
function csharp(hljs) {
const BUILT_IN_KEYWORDS = [
'bool',
'byte',
'char',
'decimal',
'delegate',
'double',
'dynamic',
'enum',
'float',
'int',
'long',
'nint',
'nuint',
'object',
'sbyte',
'short',
'string',
'ulong',
'uint',
'ushort'
];
const FUNCTION_MODIFIERS = [
'public',
'private',
'protected',
'static',
'internal',
'protected',
'abstract',
'async',
'extern',
'override',
'unsafe',
'virtual',
'new',
'sealed',
'partial'
];
const LITERAL_KEYWORDS = [
'default',
'false',
'null',
'true'
];
const CONTROL_KEYWORDS = [
'break', 'case', 'catch', 'continue', 'do', 'else', 'finally', 'fixed', 'for', 'foreach', 'goto', 'if', 'return', 'switch', 'throw', 'try', 'while', 'yield', 'await'
];
const NORMAL_KEYWORDS = [
'abstract',
'as',
'base',
'break',
'case',
'catch',
'checked',
'class',
'const',
'continue',
'do',
'else',
'event',
'explicit',
'extern',
'finally',
'fixed',
'for',
'foreach',
'goto',
'if',
'implicit',
'in',
'interface',
'internal',
'is',
'lock',
'namespace',
'new',
'operator',
'out',
'override',
'params',
'private',
'protected',
'public',
'readonly',
'record',
'ref',
'return',
'scoped',
'sealed',
'sizeof',
'stackalloc',
'static',
'struct',
'switch',
'this',
'throw',
'try',
'typeof',
'unchecked',
'unsafe',
'using',
'virtual',
'void',
'volatile',
'while'
].filter(k => !CONTROL_KEYWORDS.includes(k));
const CONTEXTUAL_KEYWORDS = [
'add',
'alias',
'and',
'ascending',
'args',
'async',
'await',
'by',
'descending',
'dynamic',
'equals',
'file',
'from',
'get',
'global',
'group',
'init',
'into',
'join',
'let',
'nameof',
'not',
'notnull',
'on',
'or',
'orderby',
'partial',
'record',
'remove',
'required',
'scoped',
'select',
'set',
'unmanaged',
'value|0',
'var',
'when',
'where',
'with',
'yield'
].filter(k => !CONTROL_KEYWORDS.includes(k));
const SYSTEM_CLASSES = [
'Boolean', 'Byte', 'Char', 'DateTime', 'DateTimeOffset', 'Decimal', 'Double', 'Guid', 'Int16', 'Int32', 'Int64', 'Object', 'SByte', 'Single', 'String', 'TimeSpan', 'UInt16', 'UInt32', 'UInt64', 'HttpListener', 'Console', 'Math', 'Environment', 'Convert', 'BitConverter', 'Random', 'Action', 'Func', 'Predicate', 'List', 'Dictionary', 'HashSet', 'Queue', 'Stack', 'LinkedList', 'Task', 'Process', 'Thread', 'File', 'Directory', 'Path', 'Stream', 'FileStream', 'MemoryStream', 'StreamReader', 'StreamWriter', 'Exception', 'StringBuilder', 'HttpClient', 'JsonConvert', 'Uri', 'CancellationToken', 'CultureInfo', 'Encoding', 'Regex', 'AppDomain', 'GC', 'UnhandledExceptionEventArgs', 'Page', 'EventArgs', 'Trace', 'Debugger', 'Application', 'App',
'QueryableJsonNode', 'LANDeviceDetector', 'TestClass', 'XFEChatGPT', 'MemorableXFEChatGPT', 'CyberCommServer', 'CyberCommClient', 'XCCNetWork', 'XFEDownloader', 'CyberCommServerEventArgs', 'CyberCommClientEventArgs',
'StaticMemoryManager', 'DynamicMemoryManager', 'UpdatableMemoryManager', 'MemoryItem', 'MemoryValue', 'MemoryManager', 'MemoryItemBuilder',
'XFEConsole', 'XFELog',
'InputSimulator',
'PageManager', 'AppThemeHelper', 'AppShellPage', 'MainPage', 'TestPage', 'ServiceManager',
'XFEProfile', 'SystemProfile', 'ProfileList', 'ProfileDictionary',
'XFEServerBuilder', 'XFEServerCoreBuilder', 'XFEClientRequesterBuilder', 'UserProfile', 'DataProfile', 'XFEDataTableManagerBuilder',
'Upgrader',
];
const SYSTEM_INTERFACES = [
'IEnumerable', 'IQueryable', 'IDisposable', 'IAsyncDisposable', 'ICloneable', 'IComparable', 'IEquatable', 'IFormatProvider', 'IFormattable', 'IServiceProvider', 'IOrderedEnumerable', 'IAsyncEnumerable', 'IReadOnlyList', 'IReadOnlyCollection', 'IReadOnlyDictionary', 'IList', 'ICollection', 'IDictionary', 'ISet', 'INotifyPropertyChanged', 'IObservable', 'IObserver', 'IActionResult', 'IAsync',
'IUserFaceInfo',
'IMessageService', 'INavigationViewService', 'ILoadingService',
];
const SYSTEM_ENUMS = [
'ConsoleColor', 'ConsoleKey', 'DateTimeKind', 'DayOfWeek', 'FileAccess', 'FileMode', 'FileShare', 'FileAttributes', 'StringSplitOptions', 'StringComparison', 'TaskStatus', 'TaskCreationOptions', 'TaskContinuationOptions', 'PlatformID', 'Point', 'ScreenPosition', 'HttpStatusCode',
'GenerateState',
'UserRole',
'MouseButton',
'InfoBarSeverity', 'ElementTheme',
];
const KEYWORDS = {
keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS),
built_in: BUILT_IN_KEYWORDS,
literal: LITERAL_KEYWORDS,
type: SYSTEM_CLASSES,
interface: SYSTEM_INTERFACES,
enum: SYSTEM_ENUMS
};
const IDENTIFIER_START_RE = '(?:[A-Za-z_]|[\\u0080-\\uFFFF])';
const IDENTIFIER_PART_RE = '(?:[A-Za-z0-9_]|[\\u0080-\\uFFFF])';
const IDENTIFIER_BOUNDARY_RE = '(?<!' + IDENTIFIER_PART_RE + ')';
const IDENTIFIER_RE = '@?' + IDENTIFIER_START_RE + IDENTIFIER_PART_RE + '*';
const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: IDENTIFIER_RE + '(\\.' + IDENTIFIER_RE + ')*' });
const NUMBERS = {
className: 'number',
variants: [
{ begin: '\\b(0b[01\']+)' },
{ begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B|d|D|m|M)' },
{ begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)' }
],
relevance: 0
};
const RAW_STRING = {
className: 'string',
begin: /"""("*)(?!")(.|\n)*?"""\1/,
relevance: 1
};
const VERBATIM_STRING = {
className: 'string',
begin: '@"',
end: '"',
contains: [{ begin: '""' }]
};
const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { illegal: /\n/ });
const SUBST = {
className: 'subst',
begin: /\{/,
end: /\}/,
keywords: KEYWORDS
};
const SUBST_NO_LF = hljs.inherit(SUBST, { illegal: /\n/ });
const INTERPOLATED_STRING = {
className: 'string',
begin: /\$"/,
end: '"',
illegal: /\n/,
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
hljs.BACKSLASH_ESCAPE,
SUBST_NO_LF
]
};
const INTERPOLATED_VERBATIM_STRING = {
className: 'string',
begin: /\$@"/,
end: '"',
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST
]
};
const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {
illegal: /\n/,
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST_NO_LF
]
});
SUBST.contains = [
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBERS,
hljs.C_BLOCK_COMMENT_MODE
];
SUBST_NO_LF.contains = [
INTERPOLATED_VERBATIM_STRING_NO_LF,
INTERPOLATED_STRING,
VERBATIM_STRING_NO_LF,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBERS,
hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { illegal: /\n/ })
];
const STRING = {
variants: [
RAW_STRING,
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
]
};
const ALL_KEYWORD_NAMES = Array.from(new Set(
NORMAL_KEYWORDS
.concat(CONTEXTUAL_KEYWORDS, CONTROL_KEYWORDS, LITERAL_KEYWORDS, BUILT_IN_KEYWORDS)
.map(keyword => keyword.replace('|0', ''))
));
const KEYWORD_SOURCE = ALL_KEYWORD_NAMES.join('|');
const TYPE_KEYWORD_GUARD_RE = '(?!(?:' + KEYWORD_SOURCE + ')\\b)';
const PREDEFINED_TYPE_NAMES = BUILT_IN_KEYWORDS
.filter(keyword => keyword !== 'delegate' && keyword !== 'enum')
.concat('void');
const PREDEFINED_TYPE_RE = '(?:' + PREDEFINED_TYPE_NAMES.join('|') + ')';
const QUALIFIED_IDENTIFIER_RE = '(?:(?:global|' + IDENTIFIER_RE + ')\\s*::\\s*)?'
+ IDENTIFIER_RE
+ '(?:\\s*\\.\\s*' + IDENTIFIER_RE + ')*';
const TYPE_SUFFIX_RE = '(?:\\s*\\?)?(?:\\s*\\[\\s*(?:,\\s*)*\\])*(?:\\s*\\*)*';
const buildGenericType = (namePattern, argumentPattern) => namePattern
+ '(?:\\s*<\\s*' + argumentPattern + '(?:\\s*,\\s*' + argumentPattern + ')*\\s*>)?'
+ TYPE_SUFFIX_RE;
const SIMPLE_TYPE_RE = QUALIFIED_IDENTIFIER_RE + TYPE_SUFFIX_RE;
const ONE_LEVEL_TYPE_RE = buildGenericType(QUALIFIED_IDENTIFIER_RE, SIMPLE_TYPE_RE);
const TYPE_REFERENCE_BODY_RE = buildGenericType(QUALIFIED_IDENTIFIER_RE, ONE_LEVEL_TYPE_RE);
const TYPE_REFERENCE_RE = IDENTIFIER_BOUNDARY_RE
+ '(?:(?=global\\s*::)|' + TYPE_KEYWORD_GUARD_RE + ')'
+ TYPE_REFERENCE_BODY_RE;
const INTERFACE_REFERENCE_RE = IDENTIFIER_BOUNDARY_RE
+ buildGenericType('I[A-Z][A-Za-z0-9_]*', ONE_LEVEL_TYPE_RE);
const DECLARATION_FOLLOW_RE = '(?=\\s+' + IDENTIFIER_RE
+ '\\s*(?:=|;|,|\\)|\\{|\\[|=>|\\bin\\b|\\())';
const PREDEFINED_TYPE_MODE = {
className: 'built_in',
begin: new RegExp('\\b' + PREDEFINED_TYPE_RE + '\\b'),
relevance: 0
};
const INTERFACE_NAME_MODE = {
className: 'interface',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + 'I[A-Z][A-Za-z0-9_]*'),
relevance: 0
};
const TYPE_NAME_MODE = {
className: 'type',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + TYPE_KEYWORD_GUARD_RE + IDENTIFIER_RE),
relevance: 0
};
const NAMED_INTERFACE_OR_TYPE = [INTERFACE_NAME_MODE, TYPE_NAME_MODE];
const GENERIC_MODIFIER = {
begin: /</,
end: />/,
relevance: 0,
contains: [
{ beginKeywords: 'in out', relevance: 0 },
PREDEFINED_TYPE_MODE,
INTERFACE_NAME_MODE,
TYPE_NAME_MODE,
'self'
]
};
const TYPE_IDENT_RE = TYPE_REFERENCE_BODY_RE;
const AT_IDENTIFIER = {
// prevents expressions like `@class` from incorrect flagging
// `class` as a keyword
begin: '@' + hljs.IDENT_RE,
relevance: 0
};
const CONSTRUCTOR_MODIFIERS = [
'public',
'private',
'protected',
'static',
'internal',
'extern',
'unsafe'
];
const CONSTRUCTOR = {
className: 'constructor',
begin: '\\b(' + CONSTRUCTOR_MODIFIERS.join('|') + ')\\s+' + IDENTIFIER_RE + '\\s*\\(',
returnBegin: true,
end: /\(/,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
{
beginKeywords: CONSTRUCTOR_MODIFIERS.join(" "),
relevance: 0
},
{
className: 'title',
begin: IDENTIFIER_RE,
relevance: 0
}
]
};
// Type names can legally use any casing. Restrict the broad rule to
// declaration syntax so expressions and ordinary variables are not
// mistaken for types.
const INTERFACE_IN_DECLARATION = {
begin: new RegExp(INTERFACE_REFERENCE_RE + DECLARATION_FOLLOW_RE),
className: 'interface',
relevance: 0
};
const TYPE_IN_DECLARATION = {
begin: new RegExp(TYPE_REFERENCE_RE + DECLARATION_FOLLOW_RE),
className: 'type',
relevance: 0
};
const rememberMemberName = match => {
symbolState.memberNames.add(normalizeIdentifier(match[0]));
};
const PROPERTY_NAME = {
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + IDENTIFIER_RE + '(?=\\s*(?:\\{|=>))'),
relevance: 0,
'on:begin': rememberMemberName
};
const PROPERTY_DECLARATION = {
begin: new RegExp(TYPE_REFERENCE_RE + '\\s+' + IDENTIFIER_RE + '\\s*(?=\\{|=>)'),
returnBegin: true,
end: /\{|=>/,
excludeEnd: true,
relevance: 0,
contains: [
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
PROPERTY_NAME
]
};
const FIELD_NAME = {
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + IDENTIFIER_RE + '(?=\\s*(?:=|;))'),
relevance: 0,
'on:begin': rememberMemberName
};
const FIELD_MODIFIERS_RE = '(?:public|private|protected|internal|static|readonly|volatile|new|unsafe|required)';
const FIELD_DECLARATION = {
begin: new RegExp('\\b(?:' + FIELD_MODIFIERS_RE + '\\s+)+' + TYPE_REFERENCE_RE
+ '\\s+' + IDENTIFIER_RE + '\\s*(?==|;)'),
returnBegin: true,
end: /=|;/,
excludeEnd: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
FIELD_NAME
]
};
const DECLARED_MEMBER_REFERENCE = {
// C# members conventionally begin with PascalCase; private fields
// commonly use an underscore. Keeping this mode narrower prevents
// ordinary camelCase locals from being consumed before VARIABLE.
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '@?(?:[A-Z_]|[\\u0080-\\uFFFF])'
+ IDENTIFIER_PART_RE + '*'),
relevance: 0,
'on:begin': (match, response) => {
if (!symbolState.memberNames.has(normalizeIdentifier(match[0]))) {
response.ignoreMatch();
}
}
};
const CONTROL_FLOW = {
className: 'csharp-keyword',
match: new RegExp('\\b(' + CONTROL_KEYWORDS.join('|') + ')\\b'),
relevance: 0
};
const FUNCTION_CALL_EXCLUSIONS = Array.from(new Set(
ALL_KEYWORD_NAMES.concat('checked', 'default', 'nameof', 'sizeof', 'typeof', 'unchecked')
)).join('|');
const FUNCTION_CALL = {
className: 'function',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '(?!(?:' + FUNCTION_CALL_EXCLUSIONS + ')\\b)'
+ IDENTIFIER_RE + '(?=\\s*(?:<[^=<>]*(?:<[^=<>]*>[^=<>]*)*>\\s*)?\\()'),
returnBegin: true,
end: /\(/,
excludeEnd: true,
relevance: 0,
contains: [
{
className: 'title',
begin: new RegExp(IDENTIFIER_RE),
relevance: 0
},
GENERIC_MODIFIER
]
};
const NEW_PREDEFINED_TYPE = {
match: [
/\bnew\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*(?:\\(|\\[|\\{))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const INSTANTIATION = {
match: [
/\bnew\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*(?:\\(|\\[|\\{))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const TYPE_OPERATOR_PREDEFINED = {
match: [
/\b(?:default|sizeof|typeof)\b/,
/\s*\(\s*/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*\\))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const TYPE_OPERATOR_UNBOUND_GENERIC = {
match: [
/\btypeof\b/,
/\s*\(\s*/,
new RegExp(IDENTIFIER_BOUNDARY_RE + QUALIFIED_IDENTIFIER_RE
+ '\\s*<\\s*(?:,\\s*)*>\\s*(?=\\))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const TYPE_OPERATOR = {
match: [
/\b(?:default|sizeof|typeof)\b/,
/\s*\(\s*/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*\\))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const AS_IS_PREDEFINED_TYPE = {
match: [
/\b(?:as|is)\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE + '(?=\\s*(?:[;,\\)\\]}]|' + IDENTIFIER_RE + '\\b))')
],
scope: {
1: 'keyword',
3: 'built_in'
},
relevance: 0
};
const AS_IS_TYPE = {
match: [
/\b(?:as|is)\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*(?:[;,\\)\\]}]|' + IDENTIFIER_RE + '\\b))')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const CAST_PREDEFINED_TYPE = {
match: [
/\(\s*/,
new RegExp(PREDEFINED_TYPE_RE),
/\s*\)(?=\s*(?:@?[A-Za-z_]|\d|["'(]))/
],
scope: { 2: 'built_in' },
relevance: 0
};
const CAST_TYPE = {
match: [
/\(\s*/,
new RegExp(TYPE_REFERENCE_RE),
/\s*\)(?=\s*(?:@?[A-Za-z_]|\d|["'(]))/
],
scope: { 2: 'type' },
relevance: 0
};
const PASCAL_STATIC_TYPE = {
className: 'type',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '[A-Z][A-Za-z0-9_]*(?=\\s*(?:\\.|::))'),
relevance: 0
};
const MEMBER_ACCESS = {
begin: new RegExp('\\.\\s*' + IDENTIFIER_RE + '(?!' + IDENTIFIER_PART_RE + ')'
+ '(?!\\s*(?:<[^=<>]*(?:<[^=<>]*>[^=<>]*)*>\\s*)?\\()'),
relevance: 0
};
const ATTRIBUTE_TARGET = {
className: 'meta',
begin: /\b(?:assembly|module|field|event|method|param|property|return|type|typevar)\s*:/,
relevance: 0
};
const ATTRIBUTE_NAME_RE = '(?:(?:global\\s*::\\s*)?'
+ '(?:' + IDENTIFIER_RE + '\\s*\\.\\s*)*)'
+ '@?[A-Z_][A-Za-z0-9_]*'
+ '(?:\\s*<[^<>\\r\\n]*(?:<[^<>\\r\\n]*>[^<>\\r\\n]*)*>)?';
const ATTRIBUTE_NAME = {
className: 'meta',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + ATTRIBUTE_NAME_RE + '(?=\\s*(?:\\(|,|\\]))'),
relevance: 0
};
const ATTRIBUTE_NESTED_BRACKETS = {
begin: /\[/,
end: /\]/,
relevance: 0,
contains: [STRING, NUMBERS, hljs.C_LINE_COMMENT_MODE, hljs.C_BLOCK_COMMENT_MODE]
};
const ATTRIBUTE_SECTION = {
begin: new RegExp('\\[(?=\\s*(?:(?:assembly|module|field|event|method|param|property|return|type|typevar)'
+ '\\s*:\\s*)?' + ATTRIBUTE_NAME_RE + ')'),
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
ATTRIBUTE_TARGET,
ATTRIBUTE_NAME,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
ATTRIBUTE_NESTED_BRACKETS
]
};
const ATTRIBUTE_ANY_NAME_RE = QUALIFIED_IDENTIFIER_RE
+ '(?:\\s*<[^<>\\r\\n]*(?:<[^<>\\r\\n]*>[^<>\\r\\n]*)*>)?';
const ATTRIBUTE_TARGET_RE = '(?:assembly|module|field|event|method|param|property|return|type|typevar)\\s*:';
const ATTRIBUTE_ANY_NAME_WITH_END_RE = ATTRIBUTE_ANY_NAME_RE + '(?=\\s*(?:\\(|,|\\]))';
const ATTRIBUTE_ANY_CONTENTS = [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
ATTRIBUTE_NAME,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
ATTRIBUTE_NESTED_BRACKETS
];
const LINE_ATTRIBUTE_SECTION = {
begin: [
/^\s*\[/,
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: { 3: 'meta' },
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const LINE_TARGET_ATTRIBUTE_SECTION = {
begin: [
/^\s*\[/,
/\s*/,
new RegExp(ATTRIBUTE_TARGET_RE),
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: {
3: 'meta',
5: 'meta'
},
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const PARAMETER_ATTRIBUTE_SECTION = {
begin: [
/\[/,
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: { 3: 'meta' },
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const PARAMETER_TARGET_ATTRIBUTE_SECTION = {
begin: [
/\[/,
/\s*/,
new RegExp(ATTRIBUTE_TARGET_RE),
/\s*/,
new RegExp(ATTRIBUTE_ANY_NAME_WITH_END_RE)
],
beginScope: {
3: 'meta',
5: 'meta'
},
end: /\]/,
relevance: 0,
keywords: KEYWORDS,
contains: ATTRIBUTE_ANY_CONTENTS
};
const DECLARATION_VARIABLE = {
className: 'variable',
begin: new RegExp(IDENTIFIER_BOUNDARY_RE + '(?!(?:' + KEYWORD_SOURCE + ')\\b)' + IDENTIFIER_RE),
relevance: 0
};
const DECLARATION_PARAMETER_LIST = {
begin: /\(/,
end: /\)/,
relevance: 0,
keywords: KEYWORDS,
contains: [
PARAMETER_TARGET_ATTRIBUTE_SECTION,
PARAMETER_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRING,
NUMBERS,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
FUNCTION_CALL,
DECLARATION_VARIABLE
]
};
const DECLARATION_CONSTRAINT_KEYWORDS = {
beginKeywords: 'where class struct notnull unmanaged new',
relevance: 0
};
const TYPE_DECLARATION_CONTENTS = [
DECLARATION_PARAMETER_LIST,
GENERIC_MODIFIER,
DECLARATION_CONSTRAINT_KEYWORDS,
PREDEFINED_TYPE_MODE,
INTERFACE_NAME_MODE,
TYPE_NAME_MODE,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
];
const CLASS_OR_STRUCT_DECLARATION = {
begin: [
/\b(?:class|struct)\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const INTERFACE_DECLARATION = {
begin: [
/\binterface\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'interface'
},
end: /[{;]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const RECORD_KIND_DECLARATION = {
begin: [
/\brecord\b/,
/\s+/,
/(?:class|struct)/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'keyword',
5: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const RECORD_DECLARATION = {
begin: [
/\brecord\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type'
},
end: /[{;=]/,
relevance: 0,
keywords: KEYWORDS,
contains: TYPE_DECLARATION_CONTENTS
};
const ENUM_DECLARATION = {
begin: [
/\benum\b/,
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'enum'
},
end: /[{;]/,
relevance: 0,
keywords: KEYWORDS,
contains: [
PREDEFINED_TYPE_MODE,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
};
const DELEGATE_PREFIX_RE = '\\b(?:(?:public|private|protected|internal|static|unsafe|new)\\s+)*delegate\\b';
const DELEGATE_PREDEFINED_DECLARATION = {
begin: [
new RegExp(DELEGATE_PREFIX_RE),
/\s+/,
new RegExp(PREDEFINED_TYPE_RE),
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'built_in',
5: 'type'
},
end: /;/,
relevance: 0,
keywords: KEYWORDS,
contains: [GENERIC_MODIFIER, DECLARATION_PARAMETER_LIST]
};
const DELEGATE_DECLARATION = {
begin: [
new RegExp(DELEGATE_PREFIX_RE),
/\s+/,
new RegExp(TYPE_REFERENCE_RE),
/\s+/,
new RegExp(IDENTIFIER_RE)
],
beginScope: {
1: 'keyword',
3: 'type',
5: 'type'
},
end: /;/,
relevance: 0,
keywords: KEYWORDS,
contains: [GENERIC_MODIFIER, DECLARATION_PARAMETER_LIST]
};
const CONVERSION_OPERATOR_PREDEFINED_TYPE = {
match: [
/\b(?:explicit|implicit)\b/,
/\s+/,
/operator\b/,
/\s+/,
new RegExp(PREDEFINED_TYPE_RE)
],
scope: {
1: 'keyword',
3: 'keyword',
5: 'built_in'
},
relevance: 0
};
const CONVERSION_OPERATOR_TYPE = {
match: [
/\b(?:explicit|implicit)\b/,
/\s+/,
/operator\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE)
],
scope: {
1: 'keyword',
3: 'keyword',
5: 'type'
},
relevance: 0
};
const OPERATOR_PREDEFINED_RETURN_TYPE = {
match: [
new RegExp(IDENTIFIER_BOUNDARY_RE + PREDEFINED_TYPE_RE),
/\s+/,
/operator\b/
],
scope: {
1: 'built_in',
3: 'keyword'
},
relevance: 0
};
const OPERATOR_RETURN_TYPE = {
match: [
new RegExp(TYPE_REFERENCE_RE),
/\s+/,
/operator\b/
],
scope: {
1: 'type',
3: 'keyword'
},
relevance: 0
};
const USING_STATIC_TYPE = {
match: [
/\busing\s+static\b/,
/\s+/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'type'
},
relevance: 0
};
const USING_ALIAS_TYPE = {
match: [
/\busing\b/,
/\s+/,
new RegExp(IDENTIFIER_RE),
/\s*=\s*/,
new RegExp(TYPE_REFERENCE_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'type',
5: 'type'
},
relevance: 0
};
const USING_NAMESPACE = {
match: [
/\busing\b/,
/\s+/,
new RegExp(QUALIFIED_IDENTIFIER_RE + '(?=\\s*;)')
],
scope: {
1: 'keyword',
3: 'namespace'
},
relevance: 0
};
const NAMESPACE_NAME = {
className: 'namespace',
begin: new RegExp(QUALIFIED_IDENTIFIER_RE),
relevance: 0
};
return {
name: 'C#',
aliases: [
'cs',
'c#'
],
keywords: KEYWORDS,
contains: [
hljs.COMMENT(
'///',
'$',
{
returnBegin: true,
contains: [
{
className: 'doctag',
variants: [
{
begin: '///',
relevance: 0
},
{ begin: '<!--|-->' },
{
begin: '</?',
end: '>'
}
]
}
]
}
),
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
LINE_TARGET_ATTRIBUTE_SECTION,
LINE_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
{
className: 'meta',
begin: '#',
end: '$',
keywords: { keyword: 'if else elif endif define undef warning error line region endregion pragma checksum nullable' }
},
STRING,
NUMBERS,
CONTROL_FLOW,
USING_STATIC_TYPE,
USING_ALIAS_TYPE,
USING_NAMESPACE,
CLASS_OR_STRUCT_DECLARATION,
INTERFACE_DECLARATION,
RECORD_KIND_DECLARATION,
RECORD_DECLARATION,
ENUM_DECLARATION,
DELEGATE_PREDEFINED_DECLARATION,
DELEGATE_DECLARATION,
CONSTRUCTOR,
NEW_PREDEFINED_TYPE,
INSTANTIATION,
TYPE_OPERATOR_PREDEFINED,
TYPE_OPERATOR_UNBOUND_GENERIC,
TYPE_OPERATOR,
AS_IS_PREDEFINED_TYPE,
AS_IS_TYPE,
CAST_PREDEFINED_TYPE,
CAST_TYPE,
CONVERSION_OPERATOR_PREDEFINED_TYPE,
CONVERSION_OPERATOR_TYPE,
OPERATOR_PREDEFINED_RETURN_TYPE,
OPERATOR_RETURN_TYPE,
PROPERTY_DECLARATION,
FIELD_DECLARATION,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
DECLARED_MEMBER_REFERENCE,
FUNCTION_CALL,
PASCAL_STATIC_TYPE,
{
beginKeywords: 'namespace',
relevance: 0,
end: /[{;=]/,
illegal: /[^\s:]/,
contains: [
NAMESPACE_NAME,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
{
// Expression keywords prevent 'keyword Name(...)' from being
// recognized as a function definition
beginKeywords: 'new return throw await else checked default nameof sizeof typeof unchecked',
relevance: 0
},
{
className: 'function',
begin: '(' + TYPE_IDENT_RE + '\\s+)+' + IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
end: /\s*[{;=]/,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
// prevents these from being highlighted `title`
{
beginKeywords: FUNCTION_MODIFIERS.join(" "),
relevance: 0
},
{
begin: IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
contains: [
hljs.TITLE_MODE,
GENERIC_MODIFIER
],
relevance: 0
},
...NAMED_INTERFACE_OR_TYPE,
{ match: /\(\)/ },
{
className: 'params',
begin: /\(/,
end: /\)/,
excludeBegin: true,
excludeEnd: true,
keywords: KEYWORDS,
relevance: 0,
contains: [
PARAMETER_TARGET_ATTRIBUTE_SECTION,
PARAMETER_ATTRIBUTE_SECTION,
ATTRIBUTE_SECTION,
STRING,
NUMBERS,
hljs.C_BLOCK_COMMENT_MODE,
INTERFACE_IN_DECLARATION,
TYPE_IN_DECLARATION,
{
className: 'variable',
begin: new RegExp('\\b(?!(?:' + KEYWORD_SOURCE + ')\\b)[a-z_][A-Za-z0-9_]*\\b'),
relevance: 0
}
]
},
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
MEMBER_ACCESS,
{
begin: '\\.' + IDENTIFIER_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
end: /[\(]/,
excludeEnd: true,
relevance: 0,
contains: [
{
begin: /\./
},
{
className: 'dotfunction',
begin: hljs.IDENT_RE,
relevance: 0
},
GENERIC_MODIFIER
]
},
{
className: 'variable',
begin: new RegExp('\\b(?!(?:' + KEYWORD_SOURCE + ')\\b)[a-z_][A-Za-z0-9_]*\\b'),
relevance: 0
},
AT_IDENTIFIER
]
};
}
csharp.resetSymbolState = () => symbolState.memberNames.clear();
return csharp;
})();
hljs.registerLanguage('csharp', hljsGrammar);
if (typeof hljs.addPlugin === 'function') {
hljs.addPlugin({
'before:highlight': context => {
if (context.language === 'csharp' || context.language === 'cs' || context.language === 'c#') {
hljsGrammar.resetSymbolState();
}
}
});
}
})();