diff --git a/components/prism-typescript.js b/components/prism-typescript.js index 1192a5414b..37fef14c67 100644 --- a/components/prism-typescript.js +++ b/components/prism-typescript.js @@ -22,6 +22,16 @@ Prism.languages.typescript['class-name'].inside = typeInside; Prism.languages.insertBefore('typescript', 'function', { + 'decorator': { + pattern: /@[$\w\xA0-\uFFFF]+/, + inside: { + 'at': { + pattern: /^@/, + alias: 'operator' + }, + 'function': /^[\s\S]+/ + } + }, 'generic-function': { // e.g. foo( ... pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/, diff --git a/components/prism-typescript.min.js b/components/prism-typescript.min.js index 67f988f3b5..d7dc6ff144 100644 --- a/components/prism-typescript.min.js +++ b/components/prism-typescript.min.js @@ -1 +1 @@ -!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},keyword:/\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),delete e.languages.typescript.parameter;var n=e.languages.extend("typescript",{});delete n["class-name"],e.languages.typescript["class-name"].inside=n,e.languages.insertBefore("typescript","function",{"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:n}}}}),e.languages.ts=e.languages.typescript}(Prism); \ No newline at end of file +!function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},keyword:/\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),delete e.languages.typescript.parameter;var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(Prism); \ No newline at end of file diff --git a/tests/languages/typescript/decorator_feature.test b/tests/languages/typescript/decorator_feature.test new file mode 100644 index 0000000000..9fc7975792 --- /dev/null +++ b/tests/languages/typescript/decorator_feature.test @@ -0,0 +1,121 @@ +@f @g x + +@f +@g +x + +@sealed +class ExampleClass { + + @first() + @second() + method() {} + + @enumerable(false) + greet() { + return "Hello, " + this.greeting; + } + + @configurable(false) + get y() { + return this._y; + } + +} + +---------------------------------------------------- + +[ + ["decorator", [ + ["at", "@"], + ["function", "f"] + ]], + ["decorator", [ + ["at", "@"], + ["function", "g"] + ]], + " x\r\n\r\n", + + ["decorator", [ + ["at", "@"], + ["function", "f"] + ]], + ["decorator", [ + ["at", "@"], + ["function", "g"] + ]], + "\r\nx\r\n\r\n", + + ["decorator", [ + ["at", "@"], + ["function", "sealed"] + ]], + ["keyword", "class"], ["class-name", ["ExampleClass"]], ["punctuation", "{"], + + ["decorator", [ + ["at", "@"], + ["function", "first"] + ]], + ["punctuation", "("], + ["punctuation", ")"], + + ["decorator", [ + ["at", "@"], + ["function", "second"] + ]], + ["punctuation", "("], + ["punctuation", ")"], + + ["function", "method"], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "{"], + ["punctuation", "}"], + + ["decorator", [ + ["at", "@"], + ["function", "enumerable"] + ]], + ["punctuation", "("], + ["boolean", "false"], + ["punctuation", ")"], + + ["function", "greet"], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "{"], + + ["keyword", "return"], + ["string", "\"Hello, \""], + ["operator", "+"], + ["keyword", "this"], + ["punctuation", "."], + "greeting", + ["punctuation", ";"], + + ["punctuation", "}"], + + ["decorator", [ + ["at", "@"], + ["function", "configurable"] + ]], + ["punctuation", "("], + ["boolean", "false"], + ["punctuation", ")"], + + ["keyword", "get"], + ["function", "y"], + ["punctuation", "("], + ["punctuation", ")"], + ["punctuation", "{"], + + ["keyword", "return"], + ["keyword", "this"], + ["punctuation", "."], + "_y", + ["punctuation", ";"], + + ["punctuation", "}"], + + ["punctuation", "}"] +] \ No newline at end of file diff --git a/tests/languages/typescript/issue2819.test b/tests/languages/typescript/issue2819.test new file mode 100644 index 0000000000..a2fd061dfc --- /dev/null +++ b/tests/languages/typescript/issue2819.test @@ -0,0 +1,38 @@ +@Component({ + selector: 'my-app', + template: `
Hello World!
` +}) +export class AppComponent {} + +---------------------------------------------------- + +[ + ["decorator", [ + ["at", "@"], + ["function", "Component"] + ]], + ["punctuation", "("], + ["punctuation", "{"], + + "\r\n selector", + ["operator", ":"], + ["string", "'my-app'"], + ["punctuation", ","], + + "\r\n template", + ["operator", ":"], + ["template-string", [ + ["template-punctuation", "`"], + ["string", "
Hello World!
"], + ["template-punctuation", "`"] + ]], + + ["punctuation", "}"], + ["punctuation", ")"], + + ["keyword", "export"], + ["keyword", "class"], + ["class-name", ["AppComponent"]], + ["punctuation", "{"], + ["punctuation", "}"] +] \ No newline at end of file