Skip to content

Commit

Permalink
Remove TypeI#toNonNullAnnotationString and fold its functionality int…
Browse files Browse the repository at this point in the history
…o #toAnnotationString via an enum Nullability { EXPLICIT, IMPLICIT }. The previous "non-null" name was misleading.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=165062947
  • Loading branch information
shicks authored and Tyler Breisacher committed Aug 15, 2017
1 parent 906545e commit d91f49a
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 50 deletions.
5 changes: 3 additions & 2 deletions src/com/google/javascript/jscomp/TypeValidator.java
Expand Up @@ -34,6 +34,7 @@
import com.google.javascript.jscomp.parsing.parser.util.format.SimpleFormat;
import com.google.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.TypeI.Nullability;
import com.google.javascript.rhino.jstype.FunctionType;
import com.google.javascript.rhino.jstype.JSType;
import com.google.javascript.rhino.jstype.JSType.SubtypingMode;
Expand Down Expand Up @@ -836,8 +837,8 @@ private static String formatFoundRequired(
String foundStr = found.toString();
String requiredStr = required.toString();
if (foundStr.equals(requiredStr)) {
foundStr = found.toAnnotationString();
requiredStr = required.toAnnotationString();
foundStr = found.toAnnotationString(Nullability.IMPLICIT);
requiredStr = required.toAnnotationString(Nullability.IMPLICIT);
}
String missingStr = "";
String mismatchStr = "";
Expand Down
23 changes: 13 additions & 10 deletions src/com/google/javascript/jscomp/TypedCodeGenerator.java
Expand Up @@ -26,6 +26,7 @@
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.TypeI;
import com.google.javascript.rhino.TypeI.Nullability;
import com.google.javascript.rhino.TypeIRegistry;
import com.google.javascript.rhino.jstype.JSTypeNative;
import java.util.Collection;
Expand Down Expand Up @@ -91,13 +92,15 @@ private String getTypeAnnotation(Node node) {
return getFunctionAnnotation(node);
} else if (type.isEnumObject()) {
return "/** @enum {"
+ type.toMaybeObjectType().getEnumeratedTypeOfEnumObject().toNonNullAnnotationString()
+ type.toMaybeObjectType()
.getEnumeratedTypeOfEnumObject()
.toAnnotationString(Nullability.EXPLICIT)
+ "} */\n";
} else if (!type.isUnknownType()
&& !type.isBottom()
&& !type.isVoidType()
&& !type.isPrototypeObject()) {
return "/** @type {" + node.getTypeI().toNonNullAnnotationString() + "} */\n";
return "/** @type {" + node.getTypeI().toAnnotationString(Nullability.EXPLICIT) + "} */\n";
} else {
return "";
}
Expand Down Expand Up @@ -153,7 +156,7 @@ private String getFunctionAnnotation(Node fnNode) {
&& !funType.isInterface() // Interfaces never return a value.
&& !(funType.isConstructor() && retType.isVoidType())) {
sb.append(" * ");
appendAnnotation(sb, "return", retType.toNonNullAnnotationString());
appendAnnotation(sb, "return", retType.toAnnotationString(Nullability.EXPLICIT));
sb.append("\n");
}

Expand All @@ -166,7 +169,7 @@ private String getFunctionAnnotation(Node fnNode) {
if (thisType != null && !thisType.isUnknownType() && !thisType.isVoidType()) {
if (fnNode == null || !thisType.equals(findMethodOwner(fnNode))) {
sb.append(" * ");
appendAnnotation(sb, "this", thisType.toNonNullAnnotationString());
appendAnnotation(sb, "this", thisType.toAnnotationString(Nullability.EXPLICIT));
sb.append("\n");
}
}
Expand All @@ -191,14 +194,14 @@ private void appendConstructorAnnotations(StringBuilder sb, FunctionTypeI funTyp
ObjectTypeI superInstance = superConstructor.getInstanceType();
if (!superInstance.toString().equals("Object")) {
sb.append(" * ");
appendAnnotation(sb, "extends", superInstance.toAnnotationString());
appendAnnotation(sb, "extends", superInstance.toAnnotationString(Nullability.IMPLICIT));
sb.append("\n");
}
}
// Avoid duplicates, add implemented type to a set first
Set<String> interfaces = new TreeSet<>();
for (ObjectTypeI interfaze : funType.getAncestorInterfaces()) {
interfaces.add(interfaze.toAnnotationString());
interfaces.add(interfaze.toAnnotationString(Nullability.IMPLICIT));
}
for (String interfaze : interfaces) {
sb.append(" * ");
Expand All @@ -211,7 +214,7 @@ private void appendConstructorAnnotations(StringBuilder sb, FunctionTypeI funTyp
private void appendInterfaceAnnotations(StringBuilder sb, FunctionTypeI funType) {
Set<String> interfaces = new TreeSet<>();
for (ObjectTypeI interfaceType : funType.getAncestorInterfaces()) {
interfaces.add(interfaceType.toAnnotationString());
interfaces.add(interfaceType.toAnnotationString(Nullability.IMPLICIT));
}
for (String interfaze : interfaces) {
sb.append(" * ");
Expand Down Expand Up @@ -258,13 +261,13 @@ private static void appendAnnotation(StringBuilder sb, String name, String type)
private String getParameterJSDocType(List<TypeI> types, int index, int minArgs, int maxArgs) {
TypeI type = types.get(index);
if (index < minArgs) {
return type.toNonNullAnnotationString();
return type.toAnnotationString(Nullability.EXPLICIT);
}
boolean isRestArgument = maxArgs == Integer.MAX_VALUE && index == types.size() - 1;
if (isRestArgument) {
return "..." + restrictByUndefined(type).toNonNullAnnotationString();
return "..." + restrictByUndefined(type).toAnnotationString(Nullability.EXPLICIT);
}
return restrictByUndefined(type).toNonNullAnnotationString() + "=";
return restrictByUndefined(type).toAnnotationString(Nullability.EXPLICIT) + "=";
}

/** Removes undefined from a union type. */
Expand Down
11 changes: 3 additions & 8 deletions src/com/google/javascript/jscomp/newtypes/JSType.java
Expand Up @@ -1702,14 +1702,9 @@ StringBuilder appendTo(StringBuilder builder, ToStringContext ctx) {
}

@Override
public final String toNonNullAnnotationString() {
return appendTo(new StringBuilder(), ToStringContext.FOR_ANNOTATION).toString();
}

@Override
public final String toAnnotationString() {
String s = toNonNullAnnotationString();
return s.startsWith("!") ? s.substring(1) : s;
public final String toAnnotationString(Nullability nullability) {
String result = appendTo(new StringBuilder(), ToStringContext.FOR_ANNOTATION).toString();
return nullability == Nullability.IMPLICIT ? result.replaceAll("^!", "") : result;
}

@Override
Expand Down
36 changes: 21 additions & 15 deletions src/com/google/javascript/rhino/TypeI.java
Expand Up @@ -204,23 +204,29 @@ public interface TypeI extends Serializable {
*/
Collection<String> getTypeParameters();

// TODO(sdh): Replace calls of toAnnotationString with toNonNullAnnotationString and
// then substring off any leading '!' if necessary. Then delete toAnnotationString
// and consider renaming toNonNullAnnotationString as simply toAnnotationString.
/**
* Returns a string representation of this type, suitable for printing
* in type annotations at code generation time. In particular, explicit
* non-null modifiers will be added to implicitly nullable types (except
* the outermost type, which is expected to be a reference type).
*/
String toAnnotationString();

/**
* Returns a string representation of this type, suitable for printing
* in type annotations at code generation time. In particular, explicit
* non-null modifiers will be added to implicitly nullable types.
*/
String toNonNullAnnotationString();
* in type annotations at code generation time.
*/
String toAnnotationString(Nullability nullability);

/**
* Specifies how to express nullability of reference types in annotation strings and error
* messages. Note that this only applies to the outer-most type. Nullability of generic type
* arguments is always explicit.
*/
enum Nullability {
/**
* Include an explicit '!' for non-nullable reference types. This is suitable for use
* in most type contexts (particularly 'type', 'param', and 'return' annotations).
*/
EXPLICIT,
/**
* Omit the explicit '!' from the outermost non-nullable reference type. This is suitable for
* use in cases where a single reference type is expected (e.g. 'extends' and 'implements').
*/
IMPLICIT,
}

/**
* Returns the type inference of this object. Useful for debugging.
Expand Down
17 changes: 4 additions & 13 deletions src/com/google/javascript/rhino/jstype/JSType.java
Expand Up @@ -1672,21 +1672,12 @@ public String toDebugHashCodeString() {
return "{" + hashCode() + "}";
}

/**
* 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.
*/
@Override
public final String toAnnotationString() {
return appendTo(new StringBuilder(), true).toString();
}

// Don't call from this package; use appendAsNonNull instead.
@Override
public final String toNonNullAnnotationString() {
return appendAsNonNull(new StringBuilder(), true).toString();
public final String toAnnotationString(Nullability nullability) {
return nullability == Nullability.EXPLICIT
? appendAsNonNull(new StringBuilder(), true).toString()
: appendTo(new StringBuilder(), true).toString();
}

final StringBuilder appendAsNonNull(StringBuilder sb, boolean forAnnotations) {
Expand Down
5 changes: 3 additions & 2 deletions test/com/google/javascript/rhino/jstype/RecordTypeTest.java
Expand Up @@ -38,6 +38,7 @@

package com.google.javascript.rhino.jstype;

import com.google.javascript.rhino.TypeI.Nullability;
import com.google.javascript.rhino.testing.Asserts;
import com.google.javascript.rhino.testing.BaseJSTypeTestCase;

Expand All @@ -57,7 +58,7 @@ public void testRecursiveRecord() {
assertEquals("{\n loop: {...},\n number: number,\n string: string\n}",
record.toString());
assertEquals("{loop: ?, number: number, string: string}",
record.toAnnotationString());
record.toAnnotationString(Nullability.EXPLICIT));

Asserts.assertEquivalenceOperations(record, loop);
}
Expand Down Expand Up @@ -94,7 +95,7 @@ public void testLongToString() {
assertEquals(
"{a01: number, a02: number, a03: number, a04: number, a05: number, a06: number," +
" a07: number, a08: number, a09: number, a10: number, a11: number}",
record.toAnnotationString());
record.toAnnotationString(Nullability.EXPLICIT));
}

public void testSupAndInf() {
Expand Down

0 comments on commit d91f49a

Please sign in to comment.