Skip to content

Commit

Permalink
Add parsing of '@externs' and '@nocompile' annotation to JsFileParser…
Browse files Browse the repository at this point in the history
… for future performance improvements.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=231427291
  • Loading branch information
DylanDavidson authored and blickly committed Jan 30, 2019
1 parent 648761e commit 60878c0
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 15 deletions.
12 changes: 12 additions & 0 deletions src/com/google/javascript/jscomp/CompilerInput.java
Expand Up @@ -190,6 +190,16 @@ public ImmutableList<String> getProvides() {
return getDependencyInfo().getProvides();
}

@Override
public boolean getHasExternsAnnotation() {
return getDependencyInfo().getHasExternsAnnotation();
}

@Override
public boolean getHasNoCompileAnnotation() {
return getDependencyInfo().getHasNoCompileAnnotation();
}

/**
* Gets a list of types provided, but does not attempt to
* regenerate the dependency information. Typically this occurs
Expand Down Expand Up @@ -271,6 +281,8 @@ private DependencyInfo getDependencyInfo() {
.setRequires(concat(dependencyInfo.getRequires(), extraRequires))
.setTypeRequires(dependencyInfo.getTypeRequires())
.setLoadFlags(dependencyInfo.getLoadFlags())
.setHasExternsAnnotation(dependencyInfo.getHasExternsAnnotation())
.setHasNoCompileAnnotation(dependencyInfo.getHasNoCompileAnnotation())
.build();
extraRequires.clear();
extraProvides.clear();
Expand Down
10 changes: 10 additions & 0 deletions src/com/google/javascript/jscomp/JSModule.java
Expand Up @@ -96,6 +96,16 @@ public ImmutableList<String> getProvides() {
return ImmutableList.of(name);
}

@Override
public boolean getHasExternsAnnotation() {
return false;
}

@Override
public boolean getHasNoCompileAnnotation() {
return false;
}

@Override
public ImmutableList<Require> getRequires() {
ImmutableList.Builder<Require> builder = ImmutableList.builder();
Expand Down
10 changes: 10 additions & 0 deletions src/com/google/javascript/jscomp/LazyParsedDependencyInfo.java
Expand Up @@ -91,4 +91,14 @@ public ImmutableList<String> getTypeRequires() {
public ImmutableList<String> getProvides() {
return delegate.getProvides();
}

@Override
public boolean getHasExternsAnnotation() {
return delegate.getHasExternsAnnotation();
}

@Override
public boolean getHasNoCompileAnnotation() {
return delegate.getHasNoCompileAnnotation();
}
}
6 changes: 6 additions & 0 deletions src/com/google/javascript/jscomp/deps/DependencyInfo.java
Expand Up @@ -145,6 +145,12 @@ abstract static class Builder {
/** Whether the symbol is provided by a module */
boolean isModule();

/** Whether the file '@externs' annotation. */
boolean getHasExternsAnnotation();

/** Whether the file has the '@nocompile' annotation. */
boolean getHasNoCompileAnnotation();

/**
* Abstract base implementation that defines derived accessors such
* as {@link #isModule}.
Expand Down
42 changes: 31 additions & 11 deletions src/com/google/javascript/jscomp/deps/JsFileLineParser.java
Expand Up @@ -130,21 +130,27 @@ void doParse(String filePath, Reader fileContents) {
String line = null;
lineNum = 0;
boolean inMultilineComment = false;
boolean inJsDocComment = false;

try {
while (null != (line = lineBuffer.readLine())) {
++lineNum;
try {
String revisedLine = line;
String revisedBlockCommentLine = "";
String revisedJsDocCommentLine = "";
if (inMultilineComment) {
int endOfComment = revisedLine.indexOf("*/");
if (endOfComment != -1) {
revisedBlockCommentLine = revisedLine.substring(0, endOfComment + 2);
if (inJsDocComment) {
revisedJsDocCommentLine = revisedLine.substring(0, endOfComment + 2);
inJsDocComment = false;
}
revisedLine = revisedLine.substring(endOfComment + 2);
inMultilineComment = false;
} else {
revisedBlockCommentLine = line;
if (inJsDocComment) {
revisedJsDocCommentLine = line;
}
revisedLine = "";
}
}
Expand All @@ -166,17 +172,25 @@ void doParse(String filePath, Reader fileContents) {
if (isCommentQuoted(revisedLine, startOfMultilineComment, '"')) {
break;
}
if (startOfMultilineComment == revisedLine.indexOf("/**")) {
inJsDocComment = true;
}
int endOfMultilineComment = revisedLine.indexOf("*/", startOfMultilineComment + 2);
if (endOfMultilineComment == -1) {
revisedBlockCommentLine = revisedLine.substring(startOfMultilineComment);
if (inJsDocComment) {
revisedJsDocCommentLine = revisedLine.substring(startOfMultilineComment);
}
revisedLine = revisedLine.substring(0, startOfMultilineComment);
inMultilineComment = true;
break;
} else {
if (!parseBlockCommentLine(
revisedLine.substring(startOfMultilineComment, endOfMultilineComment + 2))
&& shortcutMode) {
break;
if (inJsDocComment) {
String jsDocComment =
revisedLine.substring(startOfMultilineComment, endOfMultilineComment + 2);
if (!parseJsDocCommentLine(jsDocComment) && shortcutMode) {
break;
}
inJsDocComment = false;
}
revisedLine =
revisedLine.substring(0, startOfMultilineComment) +
Expand All @@ -188,8 +202,8 @@ void doParse(String filePath, Reader fileContents) {
}
}

if (!revisedBlockCommentLine.isEmpty()) {
if (!parseBlockCommentLine(revisedBlockCommentLine) && shortcutMode) {
if (!revisedJsDocCommentLine.isEmpty()) {
if (!parseJsDocCommentLine(revisedJsDocCommentLine) && shortcutMode) {
break;
}
}
Expand Down Expand Up @@ -252,7 +266,13 @@ private boolean isCommentQuoted(String line, int startOfMultilineComment, char q
*/
abstract boolean parseLine(String line) throws ParseException;

boolean parseBlockCommentLine(String line) {
/**
* Called for each JSDoc line of the file being parsed.
*
* @param line The JSDoc comment line to parse.
* @return true to keep going, false otherwise.
*/
boolean parseJsDocCommentLine(String line) {
return true;
}

Expand Down
22 changes: 21 additions & 1 deletion src/com/google/javascript/jscomp/deps/JsFileParser.java
Expand Up @@ -90,6 +90,12 @@ public final class JsFileParser extends JsFileLineParser {
/** Line in comment indicating that the file is Closure's base.js. */
private static final String PROVIDES_GOOG_COMMENT = "@provideGoog";

/** Line in comment indicating that the file is an extern. */
private static final String EXTERNS_COMMENT = "@externs";

/** Line in comment indicating that the file should not be touched by JSCompiler. */
private static final String NOCOMPILE_COMMENT = "@nocompile";

/** The start of a bundled goog.module, i.e. one that is wrapped in a goog.loadModule call */
private static final String BUNDLED_GOOG_MODULE_START = "goog.loadModule(function(";

Expand All @@ -104,6 +110,8 @@ public final class JsFileParser extends JsFileLineParser {
private List<Require> requires;
private List<String> typeRequires;
private boolean fileHasProvidesOrRequires;
private boolean hasExternsAnnotation;
private boolean hasNoCompileAnnotation;
private ModuleLoader loader = ModuleLoader.EMPTY;
private ModuleLoader.ModulePath file;

Expand Down Expand Up @@ -211,6 +219,8 @@ private DependencyInfo parseReader(String filePath,
.setRequires(requires)
.setTypeRequires(typeRequires)
.setLoadFlags(loadFlags)
.setHasExternsAnnotation(hasExternsAnnotation)
.setHasNoCompileAnnotation(hasNoCompileAnnotation)
.build();
if (logger.isLoggable(Level.FINE)) {
logger.fine("DepInfo: " + dependencyInfo);
Expand Down Expand Up @@ -245,10 +255,20 @@ private void setModuleType(ModuleType type) {
}

@Override
protected boolean parseBlockCommentLine(String line) {
protected boolean parseJsDocCommentLine(String line) {
// Since these checks are all mutually exclusive, bail out after we see the first one.
// @providesGoog should only ever be in one file (namely base.js),
// and @nocompile means the file is thrown out entirely,
// so it should never exist with @externs.
if (includeGoogBase && line.contains(PROVIDES_GOOG_COMMENT)) {
provides.add("goog");
return false;
} else if (line.contains(EXTERNS_COMMENT)) {
hasExternsAnnotation = true;
return false;
} else if (line.contains(NOCOMPILE_COMMENT)) {
hasNoCompileAnnotation = true;
return false;
}
return true;
}
Expand Down
12 changes: 10 additions & 2 deletions src/com/google/javascript/jscomp/deps/SimpleDependencyInfo.java
Expand Up @@ -36,7 +36,9 @@ public static Builder builder(String srcPathRelativeToClosure, String pathOfDefi
.setProvides(ImmutableList.of())
.setRequires(ImmutableList.of())
.setTypeRequires(ImmutableList.of())
.setLoadFlags(ImmutableMap.of());
.setLoadFlags(ImmutableMap.of())
.setHasExternsAnnotation(false)
.setHasNoCompileAnnotation(false);
}

/**
Expand All @@ -52,7 +54,9 @@ public static Builder from(DependencyInfo copy) {
.setProvides(copy.getProvides())
.setRequires(copy.getRequires())
.setTypeRequires(copy.getTypeRequires())
.setLoadFlags(copy.getLoadFlags());
.setLoadFlags(copy.getLoadFlags())
.setHasExternsAnnotation(copy.getHasExternsAnnotation())
.setHasNoCompileAnnotation(copy.getHasNoCompileAnnotation());
}

abstract Builder setName(String name);
Expand All @@ -71,6 +75,10 @@ public static Builder from(DependencyInfo copy) {

public abstract Builder setLoadFlags(Map<String, String> loadFlags);

public abstract Builder setHasExternsAnnotation(boolean hasExternsAnnotation);

public abstract Builder setHasNoCompileAnnotation(boolean hasNoCompileAnnotation);

private static final ImmutableMap<String, String> GOOG_MODULE_FLAGS =
ImmutableMap.of("module", "goog");

Expand Down
Expand Up @@ -159,7 +159,7 @@ boolean parseLine(String line) {
}

@Override
boolean parseBlockCommentLine(String line) {
boolean parseJsDocCommentLine(String line) {
comments.append(line);
return true;
}
Expand Down
83 changes: 83 additions & 0 deletions test/com/google/javascript/jscomp/deps/JsFileParserTest.java
Expand Up @@ -611,6 +611,89 @@ public void testIncludeGoog4() {
assertDeps(expected, result);
}

@Test
public void testExternsAnnotation_basic_multiline() {
String contents = "/**\n" + " * @externs\n" + " */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH).setHasExternsAnnotation(true).build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testExternsAnnotation_basic_oneLine() {
String contents = "/** @externs */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH).setHasExternsAnnotation(true).build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testExternsAnnotation_blockComment() {
String contents = "/* @externs */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH).setHasExternsAnnotation(false).build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testExternsAnnotation_blockComment_multiline() {
String contents = "/*\n @externs */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH).setHasExternsAnnotation(false).build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testNoCompileAnnotation_basic_multiline() {
String contents = "/**\n" + " * @nocompile\n" + " */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH)
.setHasNoCompileAnnotation(true)
.build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testNoCompileAnnotation_basic_oneLine() {
String contents = "/** @nocompile */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH)
.setHasNoCompileAnnotation(true)
.build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testNoCompileAnnotation_blockComment() {
String contents = "/* @nocompile */\n";

DependencyInfo expected =
SimpleDependencyInfo.builder(CLOSURE_PATH, SRC_PATH)
.setHasNoCompileAnnotation(false)
.build();
DependencyInfo result =
parser.setIncludeGoogBase(true).parseFile(SRC_PATH, CLOSURE_PATH, contents);
assertDeps(expected, result);
}

@Test
public void testParseProvidesAndWrappedGoogModule() {
String contents =
Expand Down

0 comments on commit 60878c0

Please sign in to comment.