com.google.javascript.jscomp.deps.JsFunctionParser Maven / Gradle / Ivy
/*
* Copyright 2008 The Closure Compiler Authors.
*
* 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.javascript.jscomp.deps;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.CharMatcher;
import com.google.javascript.jscomp.ErrorManager;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A parser that can extract dependency information from a .js file.
*
* @author [email protected] (Andrew Grieve)
*/
@GwtIncompatible("java.util.regex")
public final class JsFunctionParser extends JsFileLineParser {
public static class SymbolInfo {
public final String functionName;
public final String symbol;
private SymbolInfo(String functionName, String symbol) {
this.functionName = functionName;
this.symbol = symbol;
}
}
private static Logger logger =
Logger.getLogger(JsFunctionParser.class.getName());
/** Pattern for matching functions. */
private Pattern pattern;
/** Matcher used in the parsing. */
private Matcher matcher;
/** Symbols parsed. */
private Collection symbols;
/** Functions to parse */
private Collection functionsToParse;
/**
* Constructor
*
* @param functions Functions to parse.
* @param errorManager Handles parse errors.
*/
public JsFunctionParser(
Collection functions, ErrorManager errorManager) {
super(errorManager);
functionsToParse = functions;
pattern = getPattern(functions);
matcher = pattern.matcher("");
}
/**
* Constructs a pattern to extract the arguments of the given functions.
*
* @param functions Functions to parse.
* @return A pattern to extract {@code functions}' arguments.
*/
private static Pattern getPattern(Collection functions) {
StringBuilder sb = new StringBuilder("(?:^|;)\\s*(");
for (String function : functions) {
sb.append(Pattern.quote(function)).append("|");
}
// remove last '|'
sb.deleteCharAt(sb.length() - 1);
sb.append(")\\s*\\((.*?)\\)");
return Pattern.compile(sb.toString());
}
/**
* Parses the given file and returns the dependency information that it
* contained.
*
* @param filePath Path to the file to parse.
* @param fileContents The contents to parse.
* @return A collection containing all symbols found in the
* file.
*/
public Collection parseFile(
String filePath, String fileContents) {
return parseReader(filePath, new StringReader(fileContents));
}
private Collection parseReader(
String filePath, Reader fileContents) {
symbols = new ArrayList<>();
logger.fine("Parsing Source: " + filePath);
doParse(filePath, fileContents);
return symbols;
}
/**
* Parses a line of JavaScript, extracting dependency information.
*/
@Override
protected boolean parseLine(String line) throws ParseException {
boolean hasFunctions = false;
boolean parseLine = false;
// Quick sanity check that will catch most cases. This is a performance
// win for people with a lot of JS.
for (String function : functionsToParse) {
if (line.contains(function)) {
parseLine = true;
break;
}
}
if (parseLine) {
matcher.reset(line);
while (matcher.find()) {
hasFunctions = true;
String functionName = matcher.group(1);
String arg = parseJsString(matcher.group(2)); // Parse the param.
symbols.add(new SymbolInfo(functionName, arg));
}
}
return !shortcutMode || hasFunctions ||
CharMatcher.whitespace().matchesAllOf(line);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy