Skip to content

Commit

Permalink
Support type propagation of const keyword declarations in i.js files.
Browse files Browse the repository at this point in the history
This is identical to the support for type propagation for /** @const */
annotated declarations.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=137087225
  • Loading branch information
blickly committed Oct 24, 2016
1 parent cf507ea commit ddf5417
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 27 deletions.
43 changes: 23 additions & 20 deletions src/com/google/javascript/jscomp/ConvertToTypedInterface.java
Expand Up @@ -108,18 +108,18 @@ private void propagateJsdocAtName(NodeTraversal t, Node nameNode) {
private static JSDocInfo getJSDocForRhs(NodeTraversal t, Node rhs, JSDocInfo oldJSDoc) {
switch (NodeUtil.getKnownValueType(rhs)) {
case BOOLEAN:
return getTypeJSDoc(oldJSDoc, "boolean");
return getConstJSDoc(oldJSDoc, "boolean");
case NUMBER:
return getTypeJSDoc(oldJSDoc, "number");
return getConstJSDoc(oldJSDoc, "number");
case STRING:
return getTypeJSDoc(oldJSDoc, "string");
return getConstJSDoc(oldJSDoc, "string");
case NULL:
return getTypeJSDoc(oldJSDoc, "null");
return getConstJSDoc(oldJSDoc, "null");
case VOID:
return getTypeJSDoc(oldJSDoc, "void");
return getConstJSDoc(oldJSDoc, "void");
case OBJECT:
if (rhs.isRegExp()) {
return getTypeJSDoc(oldJSDoc, new Node(Token.BANG, IR.string("RegExp")));
return getConstJSDoc(oldJSDoc, new Node(Token.BANG, IR.string("RegExp")));
}
break;
case UNDETERMINED:
Expand Down Expand Up @@ -161,7 +161,7 @@ private static JSDocInfo getJSDocForName(Var decl, JSDocInfo oldJSDoc) {
default:
break;
}
return getTypeJSDoc(oldJSDoc, expr);
return getConstJSDoc(oldJSDoc, expr);
}

}
Expand Down Expand Up @@ -474,13 +474,17 @@ private void removeEnumValues(Node objLit) {
}

private static boolean isInferrableConst(JSDocInfo jsdoc, Node nameNode) {
return jsdoc != null
&& jsdoc.hasConstAnnotation()
boolean isConst =
nameNode.getParent().isConst() || (jsdoc != null && jsdoc.hasConstAnnotation());
return isConst
&& !hasAnnotatedType(jsdoc)
&& !NodeUtil.isNamespaceDecl(nameNode);
}

private static boolean hasAnnotatedType(JSDocInfo jsdoc) {
if (jsdoc == null) {
return false;
}
return jsdoc.hasType()
|| jsdoc.hasReturnType()
|| jsdoc.getParameterCount() > 0
Expand Down Expand Up @@ -518,33 +522,32 @@ private static JSDocInfo pullJsdocTypeFromAst(
JSType type = nameNode.getJSType();
if (type == null) {
compiler.report(JSError.make(nameNode, CONSTANT_WITHOUT_EXPLICIT_TYPE));
return getTypeJSDoc(oldJSDoc, new Node(Token.STAR));
return getConstJSDoc(oldJSDoc, new Node(Token.STAR));
} else {
return getTypeJSDoc(oldJSDoc, type.toNonNullAnnotationString());
return getConstJSDoc(oldJSDoc, type.toNonNullAnnotationString());
}
}

private static JSDocInfo getAllTypeJSDoc() {
JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
builder.recordType(asTypeExpression(new Node(Token.STAR)));
return builder.build();
return getConstJSDoc(null, new Node(Token.STAR));
}

private static JSTypeExpression asTypeExpression(Node typeAst) {
return new JSTypeExpression(typeAst, "<synthetic>");
}

private static JSDocInfo getTypeJSDoc(JSDocInfo oldJSDoc, String contents) {
return getTypeJSDoc(oldJSDoc, Node.newString(contents));
private static JSDocInfo getConstJSDoc(JSDocInfo oldJSDoc, String contents) {
return getConstJSDoc(oldJSDoc, Node.newString(contents));
}

private static JSDocInfo getTypeJSDoc(JSDocInfo oldJSDoc, Node typeAst) {
return getTypeJSDoc(oldJSDoc, asTypeExpression(typeAst));
private static JSDocInfo getConstJSDoc(JSDocInfo oldJSDoc, Node typeAst) {
return getConstJSDoc(oldJSDoc, asTypeExpression(typeAst));
}

private static JSDocInfo getTypeJSDoc(JSDocInfo oldJSDoc, JSTypeExpression newType) {
JSDocInfoBuilder builder = JSDocInfoBuilder.copyFrom(oldJSDoc);
private static JSDocInfo getConstJSDoc(JSDocInfo oldJSDoc, JSTypeExpression newType) {
JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(oldJSDoc);
builder.recordType(newType);
builder.recordConstancy();
return builder.build();
}
}
18 changes: 11 additions & 7 deletions test/com/google/javascript/jscomp/ConvertToTypedInterfaceTest.java
Expand Up @@ -61,14 +61,18 @@ public void testSimpleConstJsdocPropagation() {
ConvertToTypedInterface.CONSTANT_WITHOUT_EXPLICIT_TYPE);
}

public void testConstKeywordJsdocPropagation() {
testEs6("const x = 5;", "/** @const {number} */ var x;");
}

public void testThisPropertiesInConstructors() {
test(
"/** @constructor */ function Foo() { /** @const {number} */ this.x; }",
"/** @constructor */ function Foo() {} \n /** @const {number} */ Foo.prototype.x;");

test(
"/** @constructor */ function Foo() { this.x; }",
"/** @constructor */ function Foo() {} \n /** @type {*} */ Foo.prototype.x;");
"/** @constructor */ function Foo() {} \n /** @const {*} */ Foo.prototype.x;");

test(
"/** @constructor */ function Foo() { /** @type {?number} */ this.x = null; this.x = 5; }",
Expand Down Expand Up @@ -314,7 +318,7 @@ public void testEnums() {

test(
"var x = 7; /** @enum {number} */ var E = { A: x };",
"/** @type {*} */ var x; /** @enum {number} */ var E = { A: 0 };");
"/** @const {*} */ var x; /** @enum {number} */ var E = { A: 0 };");
}

public void testTryCatch() {
Expand Down Expand Up @@ -382,7 +386,7 @@ public void testLoops() {
test("while (true) { foo(); break; }", "{}");

test("for (var i = 0; i < 10; i++) { var field = 88; }",
"/** @type {*} */ var i; {/** @type {*} */ var field;}");
"/** @const {*} */ var i; {/** @const {*} */ var field;}");

test(
"while (i++ < 10) { var /** number */ field = i; }",
Expand All @@ -402,7 +406,7 @@ public void testLoops() {

test(
"for (var i = 0; i < 10; i++) { var /** number */ field = i; }",
"/** @type {*} */ var i; { /** @type {number } */ var field; }");
"/** @const {*} */ var i; { /** @type {number } */ var field; }");
}

public void testNamespaces() {
Expand All @@ -428,7 +432,7 @@ public void testRemoveRepeatedProperties() {

test(
"/** @const */ var ns = {}; ns.x = 5; ns.x = 7;",
"/** @const */ var ns = {}; /** @type {*} */ ns.x;");
"/** @const */ var ns = {}; /** @const {*} */ ns.x;");

testEs6(
"const ns = {}; /** @type {number} */ ns.x = 5; ns.x = 7;",
Expand All @@ -440,9 +444,9 @@ public void testRemoveRepeatedDeclarations() {

test("/** @type {number} */ var x = 4; x = 7;", "/** @type {number} */ var x;");

test("var x = 4; var x = 7;", "/** @type {*} */ var x;");
test("var x = 4; var x = 7;", "/** @const {*} */ var x;");

test("var x = 4; x = 7;", "/** @type {*} */ var x;");
test("var x = 4; x = 7;", "/** @const {*} */ var x;");
}

public void testDontRemoveGoogModuleContents() {
Expand Down

0 comments on commit ddf5417

Please sign in to comment.