XML editor was replaced by codemirror thridparty library and other improvements such as dynaform editor load time
This commit is contained in:
20
gulliver/js/codemirror/contrib/java/LICENSE
Executable file
20
gulliver/js/codemirror/contrib/java/LICENSE
Executable file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2010 Patrick Wied
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
64
gulliver/js/codemirror/contrib/java/css/javacolors.css
Executable file
64
gulliver/js/codemirror/contrib/java/css/javacolors.css
Executable file
@@ -0,0 +1,64 @@
|
||||
|
||||
html {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.editbox {
|
||||
margin: .4em;
|
||||
padding: 0;
|
||||
font-family: monospace;
|
||||
font-size: 10pt;
|
||||
color: black;
|
||||
}
|
||||
|
||||
pre.code, .editbox {
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.editbox p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
span.java-punctuation {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.java-operator {
|
||||
color: purple;
|
||||
}
|
||||
|
||||
span.java-keyword {
|
||||
color: #7f0055;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
span.java-atom {
|
||||
color: brown;
|
||||
}
|
||||
|
||||
span.java-variable {
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
span.java-property {
|
||||
color: black;
|
||||
}
|
||||
|
||||
span.java-comment {
|
||||
color: green;
|
||||
}
|
||||
|
||||
span.javadoc-comment {
|
||||
color: #3e5797;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
span.java-string {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
span.java-annotation{
|
||||
color: gray;
|
||||
}
|
||||
|
||||
66
gulliver/js/codemirror/contrib/java/index.html
Executable file
66
gulliver/js/codemirror/contrib/java/index.html
Executable file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Demonstration of CodeMirrors Java highlighter written by Patrick Wied</title>
|
||||
<script src="../../js/codemirror.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../css/docs.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p>Demonstration of <a href="http://www.codemirror.net">CodeMirror</a>'s Java highlighter.</p>
|
||||
|
||||
<p>Written by <a href="http://www.patrick-wied.at/">Patrick Wied</a>.</p>
|
||||
|
||||
<div style="border-top: 1px solid black; border-bottom: 1px solid black;">
|
||||
<textarea id="code">
|
||||
package example;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* This class subclasses DrawableRect and adds colors to the rectangle it draws
|
||||
**/
|
||||
public class ColoredRect extends DrawableRect {
|
||||
// These are new fields defined by this class.
|
||||
// x1, y1, x2, and y2 are inherited from our super-superclass, Rect.
|
||||
@AnnotationTest
|
||||
protected Color border, fill;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* This constructor uses super() to invoke the superclass constructor, and
|
||||
* also does some initialization of its own.
|
||||
**/
|
||||
public ColoredRect(int x1, int y1, int x2, int y2, Color border, Color fill){
|
||||
super(x1, y1, x2, y2);
|
||||
/* This
|
||||
is a block comment */
|
||||
this.border = border;
|
||||
this.fill = fill;
|
||||
this.name = "This is a string";
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overrides the draw() method of our superclass so that it
|
||||
* can make use of the colors that have been specified.
|
||||
**/
|
||||
public void draw(Graphics g) {
|
||||
g.setColor(fill);
|
||||
g.fillRect(x1, y1, x2, y2);
|
||||
g.setColor(border);
|
||||
g.drawRect(x1, y1, x2, y2);
|
||||
}
|
||||
}
|
||||
</textarea>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var editor = CodeMirror.fromTextArea('code', {
|
||||
height: "650px",
|
||||
parserfile: ["../contrib/java/js/tokenizejava.js","../contrib/java/js/parsejava.js"],
|
||||
stylesheet: "css/javacolors.css",
|
||||
path: "../../js/",
|
||||
tabMode : "shift"
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
285
gulliver/js/codemirror/contrib/java/js/parsejava.js
Executable file
285
gulliver/js/codemirror/contrib/java/js/parsejava.js
Executable file
@@ -0,0 +1,285 @@
|
||||
/**
|
||||
* Java parser for codemirror
|
||||
*
|
||||
* @author Patrick Wied
|
||||
*/
|
||||
|
||||
var JavaParser = Editor.Parser = (function() {
|
||||
// Token types that can be considered to be atoms.
|
||||
var atomicTypes = {"atom": true, "number": true, "string": true, "regexp": true};
|
||||
// Setting that can be used to have JSON data indent properly.
|
||||
var json = false;
|
||||
// Constructor for the lexical context objects.
|
||||
function JavaLexical(indented, column, type, align, prev, info) {
|
||||
// indentation at start of this line
|
||||
this.indented = indented;
|
||||
// column at which this scope was opened
|
||||
this.column = column;
|
||||
// type of scope ( 'stat' (statement), 'form' (special form), '[', '{', or '(')
|
||||
this.type = type;
|
||||
// '[', '{', or '(' blocks that have any text after their opening
|
||||
// character are said to be 'aligned' -- any lines below are
|
||||
// indented all the way to the opening character.
|
||||
if (align != null)
|
||||
this.align = align;
|
||||
// Parent scope, if any.
|
||||
this.prev = prev;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
// java indentation rules.
|
||||
function indentJava(lexical) {
|
||||
return function(firstChars) {
|
||||
var firstChar = firstChars && firstChars.charAt(0), type = lexical.type;
|
||||
var closing = firstChar == type;
|
||||
if (type == "form" && firstChar == "{")
|
||||
return lexical.indented;
|
||||
else if (type == "stat" || type == "form")
|
||||
return lexical.indented + indentUnit;
|
||||
else if (lexical.info == "switch" && !closing)
|
||||
return lexical.indented + (/^(?:case|default)\b/.test(firstChars) ? indentUnit : 2 * indentUnit);
|
||||
else if (lexical.align)
|
||||
return lexical.column - (closing ? 1 : 0);
|
||||
else
|
||||
return lexical.indented + (closing ? 0 : indentUnit);
|
||||
};
|
||||
}
|
||||
|
||||
// The parser-iterator-producing function itself.
|
||||
function parseJava(input, basecolumn) {
|
||||
// Wrap the input in a token stream
|
||||
var tokens = tokenizeJava(input);
|
||||
// The parser state. cc is a stack of actions that have to be
|
||||
// performed to finish the current statement. For example we might
|
||||
// know that we still need to find a closing parenthesis and a
|
||||
// semicolon. Actions at the end of the stack go first. It is
|
||||
// initialized with an infinitely looping action that consumes
|
||||
// whole statements.
|
||||
var cc = [statements];
|
||||
// The lexical scope, used mostly for indentation.
|
||||
var lexical = new JavaLexical(basecolumn || 0, 0, "block", false);
|
||||
// Current column, and the indentation at the start of the current
|
||||
// line. Used to create lexical scope objects.
|
||||
var column = 0;
|
||||
var indented = 0;
|
||||
// Variables which are used by the mark, cont, and pass functions
|
||||
// below to communicate with the driver loop in the 'next'
|
||||
// function.
|
||||
var consume, marked;
|
||||
|
||||
// The iterator object.
|
||||
var parser = {next: next, copy: copy};
|
||||
|
||||
function next(){
|
||||
// Start by performing any 'lexical' actions (adjusting the
|
||||
// lexical variable), or the operations below will be working
|
||||
// with the wrong lexical state.
|
||||
while(cc[cc.length - 1].lex)
|
||||
cc.pop()();
|
||||
|
||||
// Fetch a token.
|
||||
var token = tokens.next();
|
||||
|
||||
// Adjust column and indented.
|
||||
if (token.type == "whitespace" && column == 0)
|
||||
indented = token.value.length;
|
||||
column += token.value.length;
|
||||
if (token.content == "\n"){
|
||||
indented = column = 0;
|
||||
// If the lexical scope's align property is still undefined at
|
||||
// the end of the line, it is an un-aligned scope.
|
||||
if (!("align" in lexical))
|
||||
lexical.align = false;
|
||||
// Newline tokens get an indentation function associated with
|
||||
// them.
|
||||
token.indentation = indentJava(lexical);
|
||||
|
||||
}
|
||||
// No more processing for meaningless tokens.
|
||||
if (token.type == "whitespace" || token.type == "comment" || token.type == "javadoc" || token.type == "annotation")
|
||||
return token;
|
||||
|
||||
// When a meaningful token is found and the lexical scope's
|
||||
// align is undefined, it is an aligned scope.
|
||||
if (!("align" in lexical))
|
||||
lexical.align = true;
|
||||
|
||||
// Execute actions until one 'consumes' the token and we can
|
||||
// return it.
|
||||
while(true) {
|
||||
consume = marked = false;
|
||||
// Take and execute the topmost action.
|
||||
cc.pop()(token.type, token.content);
|
||||
if (consume){
|
||||
// Marked is used to change the style of the current token.
|
||||
if (marked)
|
||||
token.style = marked;
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This makes a copy of the parser state. It stores all the
|
||||
// stateful variables in a closure, and returns a function that
|
||||
// will restore them when called with a new input stream. Note
|
||||
// that the cc array has to be copied, because it is contantly
|
||||
// being modified. Lexical objects are not mutated, and context
|
||||
// objects are not mutated in a harmful way, so they can be shared
|
||||
// between runs of the parser.
|
||||
function copy(){
|
||||
var _lexical = lexical, _cc = cc.concat([]), _tokenState = tokens.state;
|
||||
|
||||
return function copyParser(input){
|
||||
lexical = _lexical;
|
||||
cc = _cc.concat([]); // copies the array
|
||||
column = indented = 0;
|
||||
tokens = tokenizeJava(input, _tokenState);
|
||||
return parser;
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function for pushing a number of actions onto the cc
|
||||
// stack in reverse order.
|
||||
function push(fs){
|
||||
for (var i = fs.length - 1; i >= 0; i--)
|
||||
cc.push(fs[i]);
|
||||
}
|
||||
// cont and pass are used by the action functions to add other
|
||||
// actions to the stack. cont will cause the current token to be
|
||||
// consumed, pass will leave it for the next action.
|
||||
function cont(){
|
||||
push(arguments);
|
||||
consume = true;
|
||||
}
|
||||
function pass(){
|
||||
push(arguments);
|
||||
consume = false;
|
||||
}
|
||||
// Used to change the style of the current token.
|
||||
function mark(style){
|
||||
marked = style;
|
||||
}
|
||||
|
||||
// Push a new lexical context of the given type.
|
||||
function pushlex(type, info) {
|
||||
var result = function(){
|
||||
lexical = new JavaLexical(indented, column, type, null, lexical, info)
|
||||
};
|
||||
result.lex = true;
|
||||
return result;
|
||||
}
|
||||
// Pop off the current lexical context.
|
||||
function poplex(){
|
||||
lexical = lexical.prev;
|
||||
}
|
||||
poplex.lex = true;
|
||||
// The 'lex' flag on these actions is used by the 'next' function
|
||||
// to know they can (and have to) be ran before moving on to the
|
||||
// next token.
|
||||
|
||||
// Creates an action that discards tokens until it finds one of
|
||||
// the given type.
|
||||
function expect(wanted){
|
||||
return function expecting(type){
|
||||
if (type == wanted) cont();
|
||||
else cont(arguments.callee);
|
||||
};
|
||||
}
|
||||
|
||||
// Looks for a statement, and then calls itself.
|
||||
function statements(type){
|
||||
return pass(statement, statements);
|
||||
}
|
||||
// Dispatches various types of statements based on the type of the
|
||||
// current token.
|
||||
function statement(type){
|
||||
if (type == "keyword a") cont(pushlex("form"), expression, statement, poplex);
|
||||
else if (type == "keyword b") cont(pushlex("form"), statement, poplex);
|
||||
else if (type == "{") cont(pushlex("}"), block, poplex);
|
||||
else if (type == "for") cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), poplex, statement, poplex);
|
||||
else if (type == "variable") cont(pushlex("stat"), maybelabel);
|
||||
else if (type == "switch") cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), block, poplex, poplex);
|
||||
else if (type == "case") cont(expression, expect(":"));
|
||||
else if (type == "default") cont(expect(":"));
|
||||
else if (type == "catch") cont(pushlex("form"), expect("("), function(){}, expect(")"), statement, poplex);
|
||||
else if (type == "class") cont();
|
||||
else if (type == "interface") cont();
|
||||
else if (type == "keyword c") cont(statement);
|
||||
else pass(pushlex("stat"), expression, expect(";"), poplex);
|
||||
}
|
||||
// Dispatch expression types.
|
||||
function expression(type){
|
||||
if (atomicTypes.hasOwnProperty(type)) cont(maybeoperator);
|
||||
//else if (type == "function") cont(functiondef);
|
||||
else if (type == "keyword c") cont(expression);
|
||||
else if (type == "(") cont(pushlex(")"), expression, expect(")"), poplex, maybeoperator);
|
||||
else if (type == "operator") cont(expression);
|
||||
else if (type == "[") cont(pushlex("]"), commasep(expression, "]"), poplex, maybeoperator);
|
||||
}
|
||||
// Called for places where operators, function calls, or
|
||||
// subscripts are valid. Will skip on to the next action if none
|
||||
// is found.
|
||||
function maybeoperator(type){
|
||||
if (type == "operator") cont(expression);
|
||||
else if (type == "(") cont(pushlex(")"), expression, commasep(expression, ")"), poplex, maybeoperator);
|
||||
else if (type == "[") cont(pushlex("]"), expression, expect("]"), poplex, maybeoperator);
|
||||
}
|
||||
// When a statement starts with a variable name, it might be a
|
||||
// label. If no colon follows, it's a regular statement.
|
||||
|
||||
function maybelabel(type){
|
||||
if (type == "(") cont(commasep(function(){}, ")"), poplex, statement); // method definition
|
||||
else if (type == "{") cont(poplex, pushlex("}"), block, poplex); // property definition
|
||||
else pass(maybeoperator, expect(";"), poplex);
|
||||
}
|
||||
|
||||
// Parses a comma-separated list of the things that are recognized
|
||||
// by the 'what' argument.
|
||||
function commasep(what, end){
|
||||
function proceed(type) {
|
||||
if (type == ",") cont(what, proceed);
|
||||
else if (type == end) cont();
|
||||
else cont(expect(end));
|
||||
};
|
||||
return function commaSeparated(type) {
|
||||
if (type == end) cont();
|
||||
else pass(what, proceed);
|
||||
};
|
||||
}
|
||||
// Look for statements until a closing brace is found.
|
||||
function block(type){
|
||||
if (type == "}") cont();
|
||||
else pass(statement, block);
|
||||
}
|
||||
|
||||
// For loops.
|
||||
|
||||
function forspec1(type){
|
||||
if (type == ";") pass(forspec2);
|
||||
else pass(forspec2);
|
||||
}
|
||||
function formaybein(type, value){
|
||||
if (value == "in") cont(expression);
|
||||
else cont(maybeoperator, forspec2);
|
||||
}
|
||||
function forspec2(type, value){
|
||||
if (type == ";") cont(forspec3);
|
||||
else if (value == "in") cont(expression);
|
||||
else cont(expression, expect(";"), forspec3);
|
||||
}
|
||||
function forspec3(type) {
|
||||
if (type == ")") pass();
|
||||
else cont(expression);
|
||||
}
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
return {
|
||||
make: parseJava,
|
||||
electricChars: "{}:",
|
||||
configure: function(obj) {
|
||||
if (obj.json != null) json = obj.json;
|
||||
}
|
||||
};
|
||||
})();
|
||||
222
gulliver/js/codemirror/contrib/java/js/tokenizejava.js
Executable file
222
gulliver/js/codemirror/contrib/java/js/tokenizejava.js
Executable file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Java tokenizer for codemirror
|
||||
*
|
||||
* @author Patrick Wied
|
||||
* @version 2010-10-07
|
||||
*/
|
||||
var tokenizeJava = (function() {
|
||||
// Advance the stream until the given character (not preceded by a
|
||||
// backslash) is encountered, or the end of the line is reached.
|
||||
function nextUntilUnescaped(source, end) {
|
||||
var escaped = false;
|
||||
var next;
|
||||
while (!source.endOfLine()) {
|
||||
var next = source.next();
|
||||
if (next == end && !escaped)
|
||||
return false;
|
||||
escaped = !escaped && next == "\\";
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
// A map of Java's keywords. The a/b/c keyword distinction is
|
||||
// very rough, but it gives the parser enough information to parse
|
||||
// correct code correctly (we don't care that much how we parse
|
||||
// incorrect code). The style information included in these objects
|
||||
// is used by the highlighter to pick the correct CSS style for a
|
||||
// token.
|
||||
var keywords = function(){
|
||||
function result(type, style){
|
||||
return {type: type, style: "java-" + style};
|
||||
}
|
||||
// keywords that take a parenthised expression, and then a
|
||||
// statement (if)
|
||||
var keywordA = result("keyword a", "keyword");
|
||||
// keywords that take just a statement (else)
|
||||
var keywordB = result("keyword b", "keyword");
|
||||
// keywords that optionally take an expression, and form a
|
||||
// statement (return)
|
||||
var keywordC = result("keyword c", "keyword");
|
||||
var operator = result("operator", "keyword");
|
||||
var atom = result("atom", "atom");
|
||||
|
||||
return {
|
||||
"if": keywordA, "while": keywordA, "with": keywordA,
|
||||
"else": keywordB, "do": keywordB, "try": keywordB, "finally": keywordB,
|
||||
"return": keywordC, "break": keywordC, "continue": keywordC, "new": keywordC, "throw": keywordC, "throws": keywordB,
|
||||
"in": operator, "typeof": operator, "instanceof": operator,
|
||||
"catch": result("catch", "keyword"), "for": result("for", "keyword"), "switch": result("switch", "keyword"),
|
||||
"case": result("case", "keyword"), "default": result("default", "keyword"),
|
||||
"true": atom, "false": atom, "null": atom,
|
||||
|
||||
"class": result("class", "keyword"), "interface": result("interface", "keyword"), "package": keywordC, "import": keywordC,
|
||||
"implements": keywordC, "extends": keywordC, "super": keywordC,
|
||||
|
||||
"public": keywordC, "private": keywordC, "protected": keywordC, "transient": keywordC, "this": keywordC,
|
||||
"static": keywordC, "final": keywordC, "const": keywordC, "abstract": keywordC, "static": keywordC,
|
||||
|
||||
"int": keywordC, "double": keywordC, "long": keywordC, "boolean": keywordC, "char": keywordC,
|
||||
"void": keywordC, "byte": keywordC, "float": keywordC, "short": keywordC
|
||||
};
|
||||
}();
|
||||
|
||||
// Some helper regexps
|
||||
var isOperatorChar = /[+\-*&%=<>!?|]/;
|
||||
var isHexDigit = /[0-9A-Fa-f]/;
|
||||
var isWordChar = /[\w\$_]/;
|
||||
// Wrapper around javaToken that helps maintain parser state (whether
|
||||
// we are inside of a multi-line comment and whether the next token
|
||||
// could be a regular expression).
|
||||
function javaTokenState(inside, regexp) {
|
||||
return function(source, setState) {
|
||||
var newInside = inside;
|
||||
var type = javaToken(inside, regexp, source, function(c) {newInside = c;});
|
||||
var newRegexp = type.type == "operator" || type.type == "keyword c" || type.type.match(/^[\[{}\(,;:]$/);
|
||||
if (newRegexp != regexp || newInside != inside)
|
||||
setState(javaTokenState(newInside, newRegexp));
|
||||
return type;
|
||||
};
|
||||
}
|
||||
|
||||
// The token reader, inteded to be used by the tokenizer from
|
||||
// tokenize.js (through jsTokenState). Advances the source stream
|
||||
// over a token, and returns an object containing the type and style
|
||||
// of that token.
|
||||
function javaToken(inside, regexp, source, setInside) {
|
||||
function readHexNumber(){
|
||||
source.next(); // skip the 'x'
|
||||
source.nextWhileMatches(isHexDigit);
|
||||
return {type: "number", style: "java-atom"};
|
||||
}
|
||||
|
||||
function readNumber() {
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
if (source.equals(".")){
|
||||
source.next();
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
}
|
||||
if (source.equals("e") || source.equals("E")){
|
||||
source.next();
|
||||
if (source.equals("-"))
|
||||
source.next();
|
||||
source.nextWhileMatches(/[0-9]/);
|
||||
}
|
||||
return {type: "number", style: "java-atom"};
|
||||
}
|
||||
// Read a word, look it up in keywords. If not found, it is a
|
||||
// variable, otherwise it is a keyword of the type found.
|
||||
function readWord() {
|
||||
source.nextWhileMatches(isWordChar);
|
||||
var word = source.get();
|
||||
var known = keywords.hasOwnProperty(word) && keywords.propertyIsEnumerable(word) && keywords[word];
|
||||
return known ? {type: known.type, style: known.style, content: word} :
|
||||
{type: "variable", style: "java-variable", content: word};
|
||||
}
|
||||
function readRegexp() {
|
||||
nextUntilUnescaped(source, "/");
|
||||
source.nextWhileMatches(/[gi]/);
|
||||
return {type: "regexp", style: "java-string"};
|
||||
}
|
||||
// Mutli-line comments are tricky. We want to return the newlines
|
||||
// embedded in them as regular newline tokens, and then continue
|
||||
// returning a comment token for every line of the comment. So
|
||||
// some state has to be saved (inside) to indicate whether we are
|
||||
// inside a /* */ sequence.
|
||||
function readMultilineComment(start){
|
||||
var newInside = "/*";
|
||||
var maybeEnd = (start == "*");
|
||||
while (true) {
|
||||
if (source.endOfLine())
|
||||
break;
|
||||
var next = source.next();
|
||||
if (next == "/" && maybeEnd){
|
||||
newInside = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (next == "*");
|
||||
}
|
||||
setInside(newInside);
|
||||
return {type: "comment", style: "java-comment"};
|
||||
}
|
||||
|
||||
// for reading javadoc
|
||||
function readJavaDocComment(start){
|
||||
var newInside = "/**";
|
||||
var maybeEnd = (start == "*");
|
||||
while (true) {
|
||||
if (source.endOfLine())
|
||||
break;
|
||||
var next = source.next();
|
||||
if (next == "/" && maybeEnd){
|
||||
newInside = null;
|
||||
break;
|
||||
}
|
||||
maybeEnd = (next == "*");
|
||||
}
|
||||
setInside(newInside);
|
||||
return {type: "javadoc", style: "javadoc-comment"};
|
||||
}
|
||||
// for reading annotations (word based)
|
||||
function readAnnotation(){
|
||||
source.nextWhileMatches(isWordChar);
|
||||
var word = source.get();
|
||||
return {type: "annotation", style: "java-annotation", content:word};
|
||||
}
|
||||
|
||||
function readOperator() {
|
||||
source.nextWhileMatches(isOperatorChar);
|
||||
return {type: "operator", style: "java-operator"};
|
||||
}
|
||||
function readString(quote) {
|
||||
var endBackSlash = nextUntilUnescaped(source, quote);
|
||||
setInside(endBackSlash ? quote : null);
|
||||
return {type: "string", style: "java-string"};
|
||||
}
|
||||
|
||||
// Fetch the next token. Dispatches on first character in the
|
||||
// stream, or first two characters when the first is a slash.
|
||||
if (inside == "\"" || inside == "'")
|
||||
return readString(inside);
|
||||
var ch = source.next();
|
||||
if (inside == "/*")
|
||||
return readMultilineComment(ch);
|
||||
else if(inside == "/**")
|
||||
return readJavaDocComment(ch);
|
||||
else if (ch == "\"" || ch == "'")
|
||||
return readString(ch);
|
||||
// with punctuation, the type of the token is the symbol itself
|
||||
else if (/[\[\]{}\(\),;\:\.]/.test(ch))
|
||||
return {type: ch, style: "java-punctuation"};
|
||||
else if (ch == "0" && (source.equals("x") || source.equals("X")))
|
||||
return readHexNumber();
|
||||
else if (/[0-9]/.test(ch))
|
||||
return readNumber();
|
||||
else if (ch == "@"){
|
||||
return readAnnotation();
|
||||
}else if (ch == "/"){
|
||||
if (source.equals("*")){
|
||||
source.next();
|
||||
|
||||
if(source.equals("*"))
|
||||
return readJavaDocComment(ch);
|
||||
|
||||
return readMultilineComment(ch);
|
||||
}
|
||||
else if (source.equals("/"))
|
||||
{ nextUntilUnescaped(source, null); return {type: "comment", style: "java-comment"};}
|
||||
else if (regexp)
|
||||
return readRegexp();
|
||||
else
|
||||
return readOperator();
|
||||
}
|
||||
else if (isOperatorChar.test(ch))
|
||||
return readOperator();
|
||||
else
|
||||
return readWord();
|
||||
}
|
||||
|
||||
// The external interface to the tokenizer.
|
||||
return function(source, startState) {
|
||||
return tokenizer(source, startState || javaTokenState(false, true));
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user