Skip to content

Commit 7ee713c

Browse files
lauraharkercopybara-github
authored andcommitted
Serialize sourceFile.getNumLines() and sourceFile.getNumBytes() in TypedAST
This avoids the need to recompute these values, and in particular to reread the JS source from disk, for certain compilations. PiperOrigin-RevId: 509251853
1 parent 8379354 commit 7ee713c

File tree

5 files changed

+498
-21
lines changed

5 files changed

+498
-21
lines changed

src/com/google/javascript/jscomp/SourceFile.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,66 @@ public static SourceFile fromCode(String fileName, String code) {
519519
return builder().withPath(fileName).withContent(code).build();
520520
}
521521

522+
/**
523+
* Reconciles serialized state in a {@link SourceFileProto} with the existing state in this file.
524+
*
525+
* <p>This should be called whenever initializing a compilation based on TypedAST protos. For
526+
* these compilations, the compiler initalization methods require creating SourceFiles before
527+
* deserializing TypedAST protos, so we sometimes get two copies of the same SourceFile.)
528+
*/
529+
public void restoreCachedStateFrom(SourceFileProto protoSourceFile) {
530+
checkState(
531+
protoSourceFile.getFilename().equals(this.getName()),
532+
"Cannot restore state for %s from %s",
533+
this.getName(),
534+
protoSourceFile.getFilename());
535+
// TypedAST proto information is expected to be more accurate for:
536+
// 1) whether a SourceFile contains an @extern annotation or not. In non-TypedAST
537+
// builds, we allow passing @extern files under the --js flag. For TypedAST builds, we
538+
// could support this, but it's an uncommon pattern and trickier to support than ban.
539+
// 2) tracking some extra state that is lazily computed in a SourceFile, like the number of
540+
// lines and bytes in a file. SourceFile::restoreCachedStateFrom handles this case.
541+
// Note: the state in the proto might be incorrect in other cases, since some state cannot be
542+
// computed during library-level typechecking (e.g. what files are in the weak chunk)
543+
if (protoSourceFile.getSourceKind() == SourceFileProto.SourceKind.EXTERN) {
544+
checkState(
545+
this.getKind() == SourceKind.EXTERN,
546+
"TypedAST compilations must pass all extern files as externs, not js, but found %s",
547+
this.getName());
548+
}
549+
550+
// Restore the number of lines/bytes from the proto, unless we already have cached
551+
// numLines and numBytes. Offset by 1. the proto "unset" value is 0, where as in SourceFile we
552+
// use "-1"
553+
int protoNumLines = protoSourceFile.getNumLinesPlusOne() - 1;
554+
int protoNumBytes = protoSourceFile.getNumBytesPlusOne() - 1;
555+
checkState(
556+
this.numLines == -1 || protoNumLines == -1 || this.numLines == protoNumLines,
557+
"Mismatch in numLines for %s. SourceFile: %s, SourceFileProto: %s",
558+
this.getName(),
559+
this.numLines,
560+
protoNumLines);
561+
checkState(
562+
this.numBytes == -1 || protoNumBytes == -1 || this.numBytes == protoNumBytes,
563+
"Mismatch in numBytes for %s. SourceFile: %s, SourceFileProto: %s",
564+
this.getName(),
565+
this.numBytes,
566+
protoNumBytes);
567+
this.numLines = this.numLines != -1 ? this.numLines : protoNumLines;
568+
this.numBytes = this.numBytes != -1 ? this.numBytes : protoNumBytes;
569+
}
570+
522571
@GwtIncompatible("java.io.Reader")
523572
public static SourceFile fromProto(SourceFileProto protoSourceFile) {
524573
SourceKind sourceKind = getSourceKindFromProto(protoSourceFile);
574+
SourceFile sourceFile = fromProto(protoSourceFile, sourceKind);
575+
// Restore the number of lines/bytes, which are offset by 1 in the proto.
576+
sourceFile.numLines = protoSourceFile.getNumLinesPlusOne() - 1;
577+
sourceFile.numBytes = protoSourceFile.getNumBytesPlusOne() - 1;
578+
return sourceFile;
579+
}
580+
581+
private static SourceFile fromProto(SourceFileProto protoSourceFile, SourceKind sourceKind) {
525582
switch (protoSourceFile.getLoaderCase()) {
526583
case PRELOADED_CONTENTS:
527584
return SourceFile.fromCode(
@@ -939,6 +996,8 @@ public SourceFileProto getProto() {
939996
.toProtoLocationBuilder(this.getName())
940997
.setFilename(this.getName())
941998
.setSourceKind(sourceKindToProto(this.getKind()))
999+
.setNumLinesPlusOne(this.numLines + 1)
1000+
.setNumBytesPlusOne(this.numBytes + 1)
9421001
.build();
9431002
}
9441003

0 commit comments

Comments
 (0)