Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/cm_modes/python.js

Issue 2166603002: DevTools: roll CodeMirror (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revert unnecessary typeIn change Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others 1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
2 // Distributed under an MIT license: http://codemirror.net/LICENSE 2 // Distributed under an MIT license: http://codemirror.net/LICENSE
3 3
4 (function(mod) { 4 (function(mod) {
5 if (typeof exports == "object" && typeof module == "object") // CommonJS 5 if (typeof exports == "object" && typeof module == "object") // CommonJS
6 mod(require("../../lib/codemirror")); 6 mod(require("../../lib/codemirror"));
7 else if (typeof define == "function" && define.amd) // AMD 7 else if (typeof define == "function" && define.amd) // AMD
8 define(["../../lib/codemirror"], mod); 8 define(["../../lib/codemirror"], mod);
9 else // Plain browser env 9 else // Plain browser env
10 mod(CodeMirror); 10 mod(CodeMirror);
11 })(function(CodeMirror) { 11 })(function(CodeMirror) {
12 "use strict"; 12 "use strict";
13 13
14 function wordRegexp(words) { 14 function wordRegexp(words) {
15 return new RegExp("^((" + words.join(")|(") + "))\\b"); 15 return new RegExp("^((" + words.join(")|(") + "))\\b");
16 } 16 }
17 17
18 var wordOperators = wordRegexp(["and", "or", "not", "is", "in"]); 18 var wordOperators = wordRegexp(["and", "or", "not", "is"]);
19 var commonKeywords = ["as", "assert", "break", "class", "continue", 19 var commonKeywords = ["as", "assert", "break", "class", "continue",
20 "def", "del", "elif", "else", "except", "finally", 20 "def", "del", "elif", "else", "except", "finally",
21 "for", "from", "global", "if", "import", 21 "for", "from", "global", "if", "import",
22 "lambda", "pass", "raise", "return", 22 "lambda", "pass", "raise", "return",
23 "try", "while", "with", "yield"]; 23 "try", "while", "with", "yield", "in"];
24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callab le", "chr", 24 var commonBuiltins = ["abs", "all", "any", "bin", "bool", "bytearray", "callab le", "chr",
25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod", 25 "classmethod", "compile", "complex", "delattr", "dict", "dir", "divmod",
26 "enumerate", "eval", "filter", "float", "format", "froze nset", 26 "enumerate", "eval", "filter", "float", "format", "froze nset",
27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id", 27 "getattr", "globals", "hasattr", "hash", "help", "hex", "id",
28 "input", "int", "isinstance", "issubclass", "iter", "len ", 28 "input", "int", "isinstance", "issubclass", "iter", "len ",
29 "list", "locals", "map", "max", "memoryview", "min", "ne xt", 29 "list", "locals", "map", "max", "memoryview", "min", "ne xt",
30 "object", "oct", "open", "ord", "pow", "property", "rang e", 30 "object", "oct", "open", "ord", "pow", "property", "rang e",
31 "repr", "reversed", "round", "set", "setattr", "slice", 31 "repr", "reversed", "round", "set", "setattr", "slice",
32 "sorted", "staticmethod", "str", "sum", "super", "tuple" , 32 "sorted", "staticmethod", "str", "sum", "super", "tuple" ,
33 "type", "vars", "zip", "__import__", "NotImplemented", 33 "type", "vars", "zip", "__import__", "NotImplemented",
34 "Ellipsis", "__debug__"]; 34 "Ellipsis", "__debug__"];
35 var py2 = {builtins: ["apply", "basestring", "buffer", "cmp", "coerce", "execf ile",
36 "file", "intern", "long", "raw_input", "reduce", "reload ",
37 "unichr", "unicode", "xrange", "False", "True", "None"],
38 keywords: ["exec", "print"]};
39 var py3 = {builtins: ["ascii", "bytes", "exec", "print"],
40 keywords: ["nonlocal", "False", "True", "None"]};
41
42 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonB uiltins)); 35 CodeMirror.registerHelper("hintWords", "python", commonKeywords.concat(commonB uiltins));
43 36
44 function top(state) { 37 function top(state) {
45 return state.scopes[state.scopes.length - 1]; 38 return state.scopes[state.scopes.length - 1];
46 } 39 }
47 40
48 CodeMirror.defineMode("python", function(conf, parserConf) { 41 CodeMirror.defineMode("python", function(conf, parserConf) {
49 var ERRORCLASS = "error"; 42 var ERRORCLASS = "error";
50 43
51 var singleOperators = parserConf.singleOperators || new RegExp("^[\\+\\-\\*/ %&|\\^~<>!]"); 44 var singleDelimiters = parserConf.singleDelimiters || /^[\(\)\[\]\{\}@,:`=;\ .]/;
52 var singleDelimiters = parserConf.singleDelimiters || new RegExp("^[\\(\\)\\ [\\]\\{\\}@,:`=;\\.]"); 45 var doubleOperators = parserConf.doubleOperators || /^([!<>]==|<>|<<|>>|\/\/ |\*\*)/;
53 var doubleOperators = parserConf.doubleOperators || new RegExp("^((==)|(!=)| (<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))"); 46 var doubleDelimiters = parserConf.doubleDelimiters || /^(\+=|\-=|\*=|%=|\/=| &=|\|=|\^=)/;
54 var doubleDelimiters = parserConf.doubleDelimiters || new RegExp("^((\\+=)|( \\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); 47 var tripleDelimiters = parserConf.tripleDelimiters || /^(\/\/=|>>=|<<=|\*\*= )/;
55 var tripleDelimiters = parserConf.tripleDelimiters || new RegExp("^((//=)|(> >=)|(<<=)|(\\*\\*=))"); 48
56 var identifiers = parserConf.identifiers|| new RegExp("^[_A-Za-z][_A-Za-z0-9 ]*");
57 var hangingIndent = parserConf.hangingIndent || conf.indentUnit; 49 var hangingIndent = parserConf.hangingIndent || conf.indentUnit;
58 50
59 var myKeywords = commonKeywords, myBuiltins = commonBuiltins; 51 var myKeywords = commonKeywords, myBuiltins = commonBuiltins;
60 if(parserConf.extra_keywords != undefined){ 52 if (parserConf.extra_keywords != undefined)
61 myKeywords = myKeywords.concat(parserConf.extra_keywords); 53 myKeywords = myKeywords.concat(parserConf.extra_keywords);
62 } 54
63 if(parserConf.extra_builtins != undefined){ 55 if (parserConf.extra_builtins != undefined)
64 myBuiltins = myBuiltins.concat(parserConf.extra_builtins); 56 myBuiltins = myBuiltins.concat(parserConf.extra_builtins);
65 } 57
66 if (parserConf.version && parseInt(parserConf.version, 10) == 3) { 58 var py3 = parserConf.version && parseInt(parserConf.version, 10) == 3
67 myKeywords = myKeywords.concat(py3.keywords); 59 if (py3) {
68 myBuiltins = myBuiltins.concat(py3.builtins); 60 // since http://legacy.python.org/dev/peps/pep-0465/ @ is also an operator
69 var stringPrefixes = new RegExp("^(([rb]|(br))?('{3}|\"{3}|['\"]))", "i"); 61 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!@] /;
62 var identifiers = parserConf.identifiers|| /^[_A-Za-z\u00A1-\uFFFF][_A-Za- z0-9\u00A1-\uFFFF]*/;
63 myKeywords = myKeywords.concat(["nonlocal", "False", "True", "None", "asyn c", "await"]);
64 myBuiltins = myBuiltins.concat(["ascii", "bytes", "exec", "print"]);
65 var stringPrefixes = new RegExp("^(([rbuf]|(br))?('{3}|\"{3}|['\"]))", "i" );
70 } else { 66 } else {
71 myKeywords = myKeywords.concat(py2.keywords); 67 var singleOperators = parserConf.singleOperators || /^[\+\-\*\/%&|\^~<>!]/ ;
72 myBuiltins = myBuiltins.concat(py2.builtins); 68 var identifiers = parserConf.identifiers|| /^[_A-Za-z][_A-Za-z0-9]*/;
69 myKeywords = myKeywords.concat(["exec", "print"]);
70 myBuiltins = myBuiltins.concat(["apply", "basestring", "buffer", "cmp", "c oerce", "execfile",
71 "file", "intern", "long", "raw_input", "re duce", "reload",
72 "unichr", "unicode", "xrange", "False", "T rue", "None"]);
73 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i"); 73 var stringPrefixes = new RegExp("^(([rub]|(ur)|(br))?('{3}|\"{3}|['\"]))", "i");
74 } 74 }
75 var keywords = wordRegexp(myKeywords); 75 var keywords = wordRegexp(myKeywords);
76 var builtins = wordRegexp(myBuiltins); 76 var builtins = wordRegexp(myBuiltins);
77 77
78 // tokenizers 78 // tokenizers
79 function tokenBase(stream, state) { 79 function tokenBase(stream, state) {
80 if (stream.sol()) state.indent = stream.indentation()
80 // Handle scope changes 81 // Handle scope changes
81 if (stream.sol() && top(state).type == "py") { 82 if (stream.sol() && top(state).type == "py") {
82 var scopeOffset = top(state).offset; 83 var scopeOffset = top(state).offset;
83 if (stream.eatSpace()) { 84 if (stream.eatSpace()) {
84 var lineOffset = stream.indentation(); 85 var lineOffset = stream.indentation();
85 if (lineOffset > scopeOffset) 86 if (lineOffset > scopeOffset)
86 pushScope(stream, state, "py"); 87 pushPyScope(state);
87 else if (lineOffset < scopeOffset && dedent(stream, state)) 88 else if (lineOffset < scopeOffset && dedent(stream, state))
88 state.errorToken = true; 89 state.errorToken = true;
89 return null; 90 return null;
90 } else { 91 } else {
91 var style = tokenBaseInner(stream, state); 92 var style = tokenBaseInner(stream, state);
92 if (scopeOffset > 0 && dedent(stream, state)) 93 if (scopeOffset > 0 && dedent(stream, state))
93 style += " " + ERRORCLASS; 94 style += " " + ERRORCLASS;
94 return style; 95 return style;
95 } 96 }
96 } 97 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 146 }
146 147
147 // Handle Strings 148 // Handle Strings
148 if (stream.match(stringPrefixes)) { 149 if (stream.match(stringPrefixes)) {
149 state.tokenize = tokenStringFactory(stream.current()); 150 state.tokenize = tokenStringFactory(stream.current());
150 return state.tokenize(stream, state); 151 return state.tokenize(stream, state);
151 } 152 }
152 153
153 // Handle operators and Delimiters 154 // Handle operators and Delimiters
154 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) 155 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters))
155 return null; 156 return "punctuation";
156 157
157 if (stream.match(doubleOperators) 158 if (stream.match(doubleOperators) || stream.match(singleOperators))
158 || stream.match(singleOperators)
159 || stream.match(wordOperators))
160 return "operator"; 159 return "operator";
161 160
162 if (stream.match(singleDelimiters)) 161 if (stream.match(singleDelimiters))
163 return null; 162 return "punctuation";
164 163
165 if (stream.match(keywords)) 164 if (state.lastToken == "." && stream.match(identifiers))
165 return "property";
166
167 if (stream.match(keywords) || stream.match(wordOperators))
166 return "keyword"; 168 return "keyword";
167 169
168 if (stream.match(builtins)) 170 if (stream.match(builtins))
169 return "builtin"; 171 return "builtin";
170 172
171 if (stream.match(/^(self|cls)\b/)) 173 if (stream.match(/^(self|cls)\b/))
172 return "variable-2"; 174 return "variable-2";
173 175
174 if (stream.match(identifiers)) { 176 if (stream.match(identifiers)) {
175 if (state.lastToken == "def" || state.lastToken == "class") 177 if (state.lastToken == "def" || state.lastToken == "class")
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 return ERRORCLASS; 210 return ERRORCLASS;
209 else 211 else
210 state.tokenize = tokenBase; 212 state.tokenize = tokenBase;
211 } 213 }
212 return OUTCLASS; 214 return OUTCLASS;
213 } 215 }
214 tokenString.isString = true; 216 tokenString.isString = true;
215 return tokenString; 217 return tokenString;
216 } 218 }
217 219
218 function pushScope(stream, state, type) { 220 function pushPyScope(state) {
219 var offset = 0, align = null; 221 while (top(state).type != "py") state.scopes.pop()
220 if (type == "py") { 222 state.scopes.push({offset: top(state).offset + conf.indentUnit,
221 while (top(state).type != "py") 223 type: "py",
222 state.scopes.pop(); 224 align: null})
223 } 225 }
224 offset = top(state).offset + (type == "py" ? conf.indentUnit : hangingInde nt); 226
225 if (type != "py" && !stream.match(/^(\s|#.*)*$/, false)) 227 function pushBracketScope(stream, state, type) {
226 align = stream.column() + 1; 228 var align = stream.match(/^([\s\[\{\(]|#.*)*$/, false) ? null : stream.col umn() + 1
227 state.scopes.push({offset: offset, type: type, align: align}); 229 state.scopes.push({offset: state.indent + hangingIndent,
230 type: type,
231 align: align})
228 } 232 }
229 233
230 function dedent(stream, state) { 234 function dedent(stream, state) {
231 var indented = stream.indentation(); 235 var indented = stream.indentation();
232 while (top(state).offset > indented) { 236 while (state.scopes.length > 1 && top(state).offset > indented) {
233 if (top(state).type != "py") return true; 237 if (top(state).type != "py") return true;
234 state.scopes.pop(); 238 state.scopes.pop();
235 } 239 }
236 return top(state).offset != indented; 240 return top(state).offset != indented;
237 } 241 }
238 242
239 function tokenLexer(stream, state) { 243 function tokenLexer(stream, state) {
244 if (stream.sol()) state.beginningOfLine = true;
245
240 var style = state.tokenize(stream, state); 246 var style = state.tokenize(stream, state);
241 var current = stream.current(); 247 var current = stream.current();
242 248
243 // Handle '.' connected identifiers 249 // Handle decorators
244 if (current == ".") { 250 if (state.beginningOfLine && current == "@")
245 style = stream.match(identifiers, false) ? null : ERRORCLASS; 251 return stream.match(identifiers, false) ? "meta" : py3 ? "operator" : ER RORCLASS;
246 if (style == null && state.lastStyle == "meta") {
247 // Apply 'meta' style to '.' connected identifiers when
248 // appropriate.
249 style = "meta";
250 }
251 return style;
252 }
253 252
254 // Handle decorators 253 if (/\S/.test(current)) state.beginningOfLine = false;
255 if (current == "@")
256 return stream.match(identifiers, false) ? "meta" : ERRORCLASS;
257 254
258 if ((style == "variable" || style == "builtin") 255 if ((style == "variable" || style == "builtin")
259 && state.lastStyle == "meta") 256 && state.lastToken == "meta")
260 style = "meta"; 257 style = "meta";
261 258
262 // Handle scope changes. 259 // Handle scope changes.
263 if (current == "pass" || current == "return") 260 if (current == "pass" || current == "return")
264 state.dedent += 1; 261 state.dedent += 1;
265 262
266 if (current == "lambda") state.lambda = true; 263 if (current == "lambda") state.lambda = true;
267 if (current == ":" && !state.lambda && top(state).type == "py") 264 if (current == ":" && !state.lambda && top(state).type == "py")
268 pushScope(stream, state, "py"); 265 pushPyScope(state);
269 266
270 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1; 267 var delimiter_index = current.length == 1 ? "[({".indexOf(current) : -1;
271 if (delimiter_index != -1) 268 if (delimiter_index != -1)
272 pushScope(stream, state, "])}".slice(delimiter_index, delimiter_index+1) ); 269 pushBracketScope(stream, state, "])}".slice(delimiter_index, delimiter_i ndex+1));
273 270
274 delimiter_index = "])}".indexOf(current); 271 delimiter_index = "])}".indexOf(current);
275 if (delimiter_index != -1) { 272 if (delimiter_index != -1) {
276 if (top(state).type == current) state.scopes.pop(); 273 if (top(state).type == current) state.indent = state.scopes.pop().offset - hangingIndent
277 else return ERRORCLASS; 274 else return ERRORCLASS;
278 } 275 }
279 if (state.dedent > 0 && stream.eol() && top(state).type == "py") { 276 if (state.dedent > 0 && stream.eol() && top(state).type == "py") {
280 if (state.scopes.length > 1) state.scopes.pop(); 277 if (state.scopes.length > 1) state.scopes.pop();
281 state.dedent -= 1; 278 state.dedent -= 1;
282 } 279 }
283 280
284 return style; 281 return style;
285 } 282 }
286 283
287 var external = { 284 var external = {
288 startState: function(basecolumn) { 285 startState: function(basecolumn) {
289 return { 286 return {
290 tokenize: tokenBase, 287 tokenize: tokenBase,
291 scopes: [{offset: basecolumn || 0, type: "py", align: null}], 288 scopes: [{offset: basecolumn || 0, type: "py", align: null}],
292 lastStyle: null, 289 indent: basecolumn || 0,
293 lastToken: null, 290 lastToken: null,
294 lambda: false, 291 lambda: false,
295 dedent: 0 292 dedent: 0
296 }; 293 };
297 }, 294 },
298 295
299 token: function(stream, state) { 296 token: function(stream, state) {
300 var addErr = state.errorToken; 297 var addErr = state.errorToken;
301 if (addErr) state.errorToken = false; 298 if (addErr) state.errorToken = false;
302 var style = tokenLexer(stream, state); 299 var style = tokenLexer(stream, state);
303 300
304 state.lastStyle = style; 301 if (style && style != "comment")
305 302 state.lastToken = (style == "keyword" || style == "punctuation") ? str eam.current() : style;
306 var current = stream.current(); 303 if (style == "punctuation") style = null;
307 if (current && style)
308 state.lastToken = current;
309 304
310 if (stream.eol() && state.lambda) 305 if (stream.eol() && state.lambda)
311 state.lambda = false; 306 state.lambda = false;
312 return addErr ? style + " " + ERRORCLASS : style; 307 return addErr ? style + " " + ERRORCLASS : style;
313 }, 308 },
314 309
315 indent: function(state, textAfter) { 310 indent: function(state, textAfter) {
316 if (state.tokenize != tokenBase) 311 if (state.tokenize != tokenBase)
317 return state.tokenize.isString ? CodeMirror.Pass : 0; 312 return state.tokenize.isString ? CodeMirror.Pass : 0;
318 313
319 var scope = top(state); 314 var scope = top(state), closing = scope.type == textAfter.charAt(0)
320 var closing = textAfter && textAfter.charAt(0) == scope.type;
321 if (scope.align != null) 315 if (scope.align != null)
322 return scope.align - (closing ? 1 : 0); 316 return scope.align - (closing ? 1 : 0)
323 else if (closing && state.scopes.length > 1)
324 return state.scopes[state.scopes.length - 2].offset;
325 else 317 else
326 return scope.offset; 318 return scope.offset - (closing ? hangingIndent : 0)
327 }, 319 },
328 320
321 electricInput: /^\s*[\}\]\)]$/,
322 closeBrackets: {triples: "'\""},
329 lineComment: "#", 323 lineComment: "#",
330 fold: "indent" 324 fold: "indent"
331 }; 325 };
332 return external; 326 return external;
333 }); 327 });
334 328
335 CodeMirror.defineMIME("text/x-python", "python"); 329 CodeMirror.defineMIME("text/x-python", "python");
336 330
337 var words = function(str) { return str.split(" "); }; 331 var words = function(str) { return str.split(" "); };
338 332
339 CodeMirror.defineMIME("text/x-cython", { 333 CodeMirror.defineMIME("text/x-cython", {
340 name: "python", 334 name: "python",
341 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+ 335 extra_keywords: words("by cdef cimport cpdef ctypedef enum except"+
342 "extern gil include nogil property public"+ 336 "extern gil include nogil property public"+
343 "readonly struct union DEF IF ELIF ELSE") 337 "readonly struct union DEF IF ELIF ELSE")
344 }); 338 });
345 339
346 }); 340 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698