// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.collide.client.code.autocomplete.codegraph.js;
import static com.google.collide.codemirror2.TokenType.DEF;
import static com.google.collide.codemirror2.TokenType.KEYWORD;
import static com.google.collide.codemirror2.TokenType.NEWLINE;
import static com.google.collide.codemirror2.TokenType.VARIABLE;
import static com.google.collide.codemirror2.TokenType.VARIABLE2;
import static com.google.collide.codemirror2.TokenType.WHITESPACE;
import com.google.collide.codemirror2.Token;
import com.google.collide.codemirror2.TokenType;
import com.google.collide.json.shared.JsonArray;
/**
* JavaScript specific parsing task.
*
* <p>This class recognizes variables and function names in stream of tokens.
*/
@Deprecated
class JsParsingTask /*extends ParsingTask*/ {
private static final String LITERAL_FUNCTION = "function";
private static boolean isVariable(TokenType type) {
return VARIABLE == type || VARIABLE2 == type || DEF == type;
}
/**
* Parsing context stores 2 previous tokens to make it possible to find some
* of the cases when a token is recognized as a function.
*
* Tries to understand the following sequences of tokens to extract
* function names: <ul>
* <li>function <i>id</i></li>
* <li><i>id</i> : function </li>
* <li><i>id</i> = function </li>
* <li><i>id</i>(</li>
* </ul>
*/
private static class JsParsingContext {
private static final String COLON_OPERATOR = ":";
private static final String EQUALS_OPERATOR = "=";
private static final String LEFT_PAR = "(";
private Token pred = null;
private Token predpred = null;
/**
* Finds cases when a token might be recognized as a function.
*
* <p>nextToken is not pushed to the context, but used for analysis.
* That way we have 3 sequential tokens to analyse:
* {@code predPred, pred, nextToken}.
*
* @param nextToken a token that is going to be pushed to context
* @return a token that might be a function or {@code null} if there is
* no sign of a function
*/
Token getFunctionToken(Token nextToken) {
if (pred == null) {
return null;
}
if (KEYWORD == pred.getType() && LITERAL_FUNCTION.equals(pred.getValue())) {
return nextToken;
}
if (LEFT_PAR.equals(nextToken.getValue()) && isVariable(pred.getType())) {
return pred;
}
if (KEYWORD == nextToken.getType() && LITERAL_FUNCTION.equals(nextToken.getValue())
&& predpred != null && isVariable(predpred.getType())
&& (COLON_OPERATOR.equals(pred.getValue()) || EQUALS_OPERATOR.equals(pred.getValue()))) {
return predpred;
}
return null;
}
/**
* Consumes next token.
*
* <p>Tokens that hold no information are omitted.
*
* @param nextToken token to push to context
*/
private void nextToken(Token nextToken) {
TokenType nextTokenType = nextToken.getType();
if (WHITESPACE != nextTokenType && NEWLINE != nextTokenType) {
predpred = pred;
pred = nextToken;
}
}
}
// @Override
protected void processLine(int lineNumber, JsonArray<Token> tokens) {
JsParsingContext context = new JsParsingContext();
for (int i = 0; i < tokens.size(); i++) {
Token token = tokens.get(i);
if (isVariable(token.getType())) {
// getResultScope().addToken(
// lineNumber, 0, new CodeToken(token.getValue().trim(), token.getType()));
}
Token functionToken = context.getFunctionToken(token);
if (functionToken != null) {
// getResultScope().addToken(lineNumber, 0,
// new CodeToken(functionToken.getValue().trim(), functionToken.getType(), true));
}
context.nextToken(token);
}
}
}