From db62891c78fb9240ad9e4020020e7ed81a03ef6a Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier <bussonniermatthias@gmail.com> Date: Tue, 19 Apr 2016 10:24:13 +0200 Subject: [PATCH] [Python] distinguish decorator at beginning of line from __matmul__ @ as __matmul__ operator only on Python 3, Add tests for Python mode for this use case. Closes #3957 --- mode/python/python.js | 19 ++++++++++++++----- mode/python/test.js | 28 ++++++++++++++++++++++++++++ test/index.html | 2 ++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 mode/python/test.js diff --git a/mode/python/python.js b/mode/python/python.js index 9160b8e74..95e4d1fe9 100644 --- a/mode/python/python.js +++ b/mode/python/python.js @@ -249,15 +249,24 @@ } function tokenLexer(stream, state) { + var sol = stream.sol(); + if (sol){ + state.whiteSpaceAtBeginningOfLine = true; + } var style = state.tokenize(stream, state); var current = stream.current(); // Handle decorators - if (current == "@") { - if (parserConf.version && parseInt(parserConf.version, 10) == 3) - return stream.match(identifiers, false) ? "meta" : "operator"; - else - return stream.match(identifiers, false) ? "meta" : ERRORCLASS; + if (state.whiteSpaceAtBeginningOfLine){ + if (current == "@") { + if (parserConf.version && parseInt(parserConf.version, 10) == 3) + return stream.match(identifiers, false) ? "meta" : "operator"; + else + return stream.match(identifiers, false) ? "meta" : ERRORCLASS; + } + } + if(!current.match(/^ +$/, false)){ + state.whiteSpaceAtBeginningOfLine = false; } if ((style == "variable" || style == "builtin") diff --git a/mode/python/test.js b/mode/python/test.js new file mode 100644 index 000000000..342c6cf33 --- /dev/null +++ b/mode/python/test.js @@ -0,0 +1,28 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function() { + var mode = CodeMirror.getMode({indentUnit: 4}, + {name: "python", + version: 3, + singleLineStringErrors: false}); + function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } + + // Error, because "foobarhello" is neither a known type or property, but + // property was expected (after "and"), and it should be in parentheses. + MT("decoratorStartOfLine", + "[meta @dec]", + "[keyword def] [def function]():", + " [keyword pass]"); + + MT("decoratorIndented", + "[keyword class] [def Foo]:", + " [meta @dec]", + " [keyword def] [def function]():", + " [keyword pass]"); + + MT("matmulWithSpace:", "[variable a] [operator @] [variable b]"); + MT("matmulWithoutSpace:", "[variable a][operator @][variable b]"); + MT("matmulSpaceBefore:", "[variable a] [operator @][variable b]"); + +})(); diff --git a/test/index.html b/test/index.html index 68dc4dfc0..90c033517 100644 --- a/test/index.html +++ b/test/index.html @@ -27,6 +27,7 @@ <script src="../mode/jsx/jsx.js"></script> <script src="../mode/markdown/markdown.js"></script> <script src="../mode/php/php.js"></script> +<script src="../mode/python/python.js"></script> <script src="../mode/powershell/powershell.js"></script> <script src="../mode/ruby/ruby.js"></script> <script src="../mode/shell/shell.js"></script> @@ -123,6 +124,7 @@ <script src="../mode/verilog/test.js"></script> <script src="../mode/xml/test.js"></script> <script src="../mode/xquery/test.js"></script> + <script src="../mode/python/test.js"></script> <script src="../mode/rust/test.js"></script> <script src="../mode/mscgen/mscgen_test.js"></script> <script src="../mode/mscgen/xu_test.js"></script> -- GitLab