Skip to content

Commit

Permalink
Change JSType#toString to thread through a StringBuilder and construc…
Browse files Browse the repository at this point in the history
…t the type string only at the end.

Currently, types that contain nested types (PrototypeObjectType, UnionType, and TemplatizedType) call JSType#toString or its friends instead of appending to one StringBuilder. This can create unnecessarily many strings.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=144236240
  • Loading branch information
dimvar authored and blickly committed Jan 12, 2017
1 parent b5615b1 commit cee6a33
Show file tree
Hide file tree
Showing 22 changed files with 135 additions and 151 deletions.
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/AllType.java
Expand Up @@ -81,8 +81,8 @@ public TernaryValue testForEquality(JSType that) {
}

@Override
String toStringHelper(boolean forAnnotations) {
return "*";
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append("*");
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/ArrowType.java
Expand Up @@ -287,8 +287,8 @@ boolean hasUnknownParamsOrReturn() {
}

@Override
String toStringHelper(boolean forAnnotations) {
return "[ArrowType]";
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append("[ArrowType]");
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/BooleanType.java
Expand Up @@ -99,8 +99,8 @@ public JSType autoboxesTo() {
}

@Override
String toStringHelper(boolean forAnnotations) {
return getDisplayName();
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(getDisplayName());
}

@Override
Expand Down
9 changes: 5 additions & 4 deletions src/com/google/javascript/rhino/jstype/EnumElementType.java
Expand Up @@ -146,10 +146,11 @@ public int hashCode() {
}

@Override
String toStringHelper(boolean forAnnotations) {
return forAnnotations ?
primitiveType.toString() :
(getReferenceName() + "<" + primitiveType + ">");
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
if (forAnnotations) {
return sb.append(this.primitiveType);
}
return sb.append(getReferenceName()).append("<").append(this.primitiveType).append(">");
}

@Override
Expand Down
5 changes: 2 additions & 3 deletions src/com/google/javascript/rhino/jstype/EnumType.java
Expand Up @@ -44,7 +44,6 @@

import com.google.javascript.rhino.ErrorReporter;
import com.google.javascript.rhino.Node;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
Expand Down Expand Up @@ -133,8 +132,8 @@ protected boolean isSubtype(JSType that,
}

@Override
String toStringHelper(boolean forAnnotations) {
return forAnnotations ? "Object" : getReferenceName();
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(forAnnotations ? "Object" : getReferenceName());
}

@Override
Expand Down
48 changes: 23 additions & 25 deletions src/com/google/javascript/rhino/jstype/FunctionType.java
Expand Up @@ -1008,79 +1008,77 @@ public boolean hasEqualCallType(FunctionType otherType) {
* {@code this:T} if the function expects a known type for {@code this}.
*/
@Override
String toStringHelper(boolean forAnnotations) {
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
if (!isPrettyPrint() ||
this == registry.getNativeType(JSTypeNative.FUNCTION_INSTANCE_TYPE)) {
return "Function";
return sb.append("Function");
}

setPrettyPrint(false);

StringBuilder b = new StringBuilder(32);
b.append("function (");
sb.append("function (");
int paramNum = call.parameters.getChildCount();
boolean hasKnownTypeOfThis = !(typeOfThis instanceof UnknownType);
if (hasKnownTypeOfThis) {
if (isConstructor()) {
b.append("new:");
sb.append("new:");
} else {
b.append("this:");
sb.append("this:");
}
b.append(typeOfThis.toStringHelper(forAnnotations));
typeOfThis.appendTo(sb, forAnnotations);
}
if (paramNum > 0) {
if (hasKnownTypeOfThis) {
b.append(", ");
sb.append(", ");
}
Node p = call.parameters.getFirstChild();
appendArgString(b, p, forAnnotations);
appendArgString(sb, p, forAnnotations);

p = p.getNext();
while (p != null) {
b.append(", ");
appendArgString(b, p, forAnnotations);
sb.append(", ");
appendArgString(sb, p, forAnnotations);
p = p.getNext();
}
}
b.append("): ");
b.append(call.returnType.toNonNullString(forAnnotations));
sb.append("): ");
call.returnType.appendAsNonNull(sb, forAnnotations);

setPrettyPrint(true);
return b.toString();
return sb;
}

private void appendArgString(
StringBuilder b, Node p, boolean forAnnotations) {
private void appendArgString(StringBuilder sb, Node p, boolean forAnnotations) {
if (p.isVarArgs()) {
appendVarArgsString(b, p.getJSType(), forAnnotations);
appendVarArgsString(sb, p.getJSType(), forAnnotations);
} else if (p.isOptionalArg()) {
appendOptionalArgString(b, p.getJSType(), forAnnotations);
appendOptionalArgString(sb, p.getJSType(), forAnnotations);
} else {
b.append(p.getJSType().toNonNullString(forAnnotations));
p.getJSType().appendAsNonNull(sb, forAnnotations);
}
}

/** Gets the string representation of a var args param. */
private void appendVarArgsString(StringBuilder builder, JSType paramType,
boolean forAnnotations) {
private void appendVarArgsString(
StringBuilder sb, JSType paramType, boolean forAnnotations) {
if (paramType.isUnionType()) {
// Remove the optionality from the var arg.
paramType = paramType.toMaybeUnionType().getRestrictedUnion(
registry.getNativeType(JSTypeNative.VOID_TYPE));
}
builder.append("...").append(
paramType.toNonNullString(forAnnotations));
sb.append("...");
paramType.appendAsNonNull(sb, forAnnotations);
}

/** Gets the string representation of an optional param. */
private void appendOptionalArgString(
StringBuilder builder, JSType paramType, boolean forAnnotations) {
StringBuilder sb, JSType paramType, boolean forAnnotations) {
if (paramType.isUnionType()) {
// Remove the optionality from the var arg.
paramType = paramType.toMaybeUnionType().getRestrictedUnion(
registry.getNativeType(JSTypeNative.VOID_TYPE));
}
builder.append(paramType.toNonNullString(forAnnotations)).append("=");
paramType.appendAsNonNull(sb, forAnnotations).append("=");
}

/**
Expand Down
10 changes: 4 additions & 6 deletions src/com/google/javascript/rhino/jstype/InstanceObjectType.java
Expand Up @@ -93,12 +93,10 @@ boolean defineProperty(String name, JSType type, boolean inferred,
}

@Override
String toStringHelper(boolean forAnnotations) {
if (constructor.hasReferenceName()) {
return constructor.getReferenceName();
} else {
return super.toStringHelper(forAnnotations);
}
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return constructor.hasReferenceName()
? sb.append(constructor.getReferenceName())
: super.appendTo(sb, forAnnotations);
}

@Override
Expand Down
30 changes: 14 additions & 16 deletions src/com/google/javascript/rhino/jstype/JSType.java
Expand Up @@ -1578,7 +1578,7 @@ public TypePair(JSType typeA, JSType typeB) {
*/
@Override
public String toString() {
return toStringHelper(false);
return appendTo(new StringBuilder(), false).toString();
}

/**
Expand All @@ -1592,29 +1592,27 @@ public String toDebugHashCodeString() {
/**
* A string representation of this type, suitable for printing
* in type annotations at code generation time.
*
* Don't call from this package; use appendAsNonNull instead.
*/
public final String toAnnotationString() {
return toStringHelper(true);
return appendTo(new StringBuilder(), true).toString();
}

public final String toNonNullString(boolean forAnnotations) {
if (forAnnotations) {
return toNonNullAnnotationString();
} else {
return toStringHelper(false);
}
// Don't call from this package; use appendAsNonNull instead.
public final String toNonNullAnnotationString() {
return appendAsNonNull(new StringBuilder(), true).toString();
}

public final String toNonNullAnnotationString() {
return !isUnknownType() && !isTemplateType() && !isRecordType() && !isFunctionType()
&& isObject() ? "!" + toAnnotationString() : toAnnotationString();
final StringBuilder appendAsNonNull(StringBuilder sb, boolean forAnnotations) {
if (forAnnotations && isObject()
&& !isUnknownType() && !isTemplateType() && !isRecordType() && !isFunctionType()) {
sb.append("!");
}
return appendTo(sb, forAnnotations);
}

/**
* @param forAnnotations Whether this is for use in code generator
* annotations. Otherwise, it's for warnings.
*/
abstract String toStringHelper(boolean forAnnotations);
abstract StringBuilder appendTo(StringBuilder sb, boolean forAnnotations);

/**
* Modify this type so that it matches the specified type.
Expand Down
5 changes: 2 additions & 3 deletions src/com/google/javascript/rhino/jstype/NamedType.java
Expand Up @@ -43,7 +43,6 @@
import com.google.common.base.Predicate;
import com.google.javascript.rhino.ErrorReporter;
import com.google.javascript.rhino.Node;

import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -153,8 +152,8 @@ public String getReferenceName() {
}

@Override
String toStringHelper(boolean forAnnotations) {
return reference;
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(this.reference);
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/NoObjectType.java
Expand Up @@ -162,8 +162,8 @@ public <T> T visit(Visitor<T> visitor) {
}

@Override
String toStringHelper(boolean forAnnotations) {
return forAnnotations ? "?" : "NoObject";
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(forAnnotations ? "?" : "NoObject");
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/NoResolvedType.java
Expand Up @@ -89,7 +89,7 @@ protected boolean isSubtype(JSType that,
}

@Override
String toStringHelper(boolean forAnnotations) {
return forAnnotations ? "?" : "NoResolvedType";
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(forAnnotations ? "?" : "NoResolvedType");
}
}
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/NoType.java
Expand Up @@ -122,7 +122,7 @@ public <T> T visit(Visitor<T> visitor) {
}

@Override
String toStringHelper(boolean forAnnotations) {
return forAnnotations ? "?" : "None";
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(forAnnotations ? "?" : "None");
}
}
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/NullType.java
Expand Up @@ -100,8 +100,8 @@ public TernaryValue testForEquality(JSType that) {
}

@Override
String toStringHelper(boolean forAnnotations) {
return getDisplayName();
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(getDisplayName());
}

@Override
Expand Down
4 changes: 2 additions & 2 deletions src/com/google/javascript/rhino/jstype/NumberType.java
Expand Up @@ -93,8 +93,8 @@ public boolean matchesObjectContext() {
}

@Override
String toStringHelper(boolean forAnnotations) {
return getDisplayName();
StringBuilder appendTo(StringBuilder sb, boolean forAnnotations) {
return sb.append(getDisplayName());
}

@Override
Expand Down

0 comments on commit cee6a33

Please sign in to comment.