Skip to content

Commit

Permalink
[NTI] Call delegate coding conventions during NTI.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=171239024
  • Loading branch information
shicks authored and dimvar committed Oct 6, 2017
1 parent 00991f3 commit 01a7a90
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 2 deletions.
50 changes: 50 additions & 0 deletions src/com/google/javascript/jscomp/GlobalTypeInfoCollector.java
Expand Up @@ -19,6 +19,7 @@
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.javascript.rhino.jstype.JSTypeNative.U2U_CONSTRUCTOR_TYPE;


import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashBasedTable;
Expand All @@ -30,6 +31,7 @@
import com.google.common.collect.MultimapBuilder; import com.google.common.collect.MultimapBuilder;
import com.google.javascript.jscomp.AbstractCompiler.MostRecentTypechecker; import com.google.javascript.jscomp.AbstractCompiler.MostRecentTypechecker;
import com.google.javascript.jscomp.CodingConvention.Bind; import com.google.javascript.jscomp.CodingConvention.Bind;
import com.google.javascript.jscomp.CodingConvention.DelegateRelationship;
import com.google.javascript.jscomp.CodingConvention.SubclassRelationship; import com.google.javascript.jscomp.CodingConvention.SubclassRelationship;
import com.google.javascript.jscomp.NewTypeInference.WarningReporter; import com.google.javascript.jscomp.NewTypeInference.WarningReporter;
import com.google.javascript.jscomp.NodeTraversal.AbstractShallowCallback; import com.google.javascript.jscomp.NodeTraversal.AbstractShallowCallback;
Expand All @@ -54,10 +56,12 @@
import com.google.javascript.rhino.IR; import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.NominalTypeBuilder;
import com.google.javascript.rhino.Token; import com.google.javascript.rhino.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
Expand Down Expand Up @@ -1427,6 +1431,8 @@ private void visitNewCtorWithoutFunctionLiteral(Node qnameNode) {


private class ProcessScope extends AbstractShallowCallback { private class ProcessScope extends AbstractShallowCallback {
private final NTIScope currentScope; private final NTIScope currentScope;
private final List<NominalTypeBuilder> delegateProxies = new ArrayList<>();
private final Map<String, String> delegateCallingConventions = new HashMap<>();
private Set<Node> lendsObjlits = new LinkedHashSet<>(); private Set<Node> lendsObjlits = new LinkedHashSet<>();


ProcessScope(NTIScope currentScope) { ProcessScope(NTIScope currentScope) {
Expand All @@ -1438,6 +1444,8 @@ void finishProcessingScope() {
processLendsNode(objlit); processLendsNode(objlit);
} }
lendsObjlits = null; lendsObjlits = null;
convention.defineDelegateProxyPrototypeProperties(
globalTypeInfo, delegateProxies, delegateCallingConventions);
} }


/** /**
Expand Down Expand Up @@ -1564,6 +1572,7 @@ public void visit(NodeTraversal t, Node n, Node parent) {
if (parent.isExprResult() && n.isQualifiedName()) { if (parent.isExprResult() && n.isQualifiedName()) {
visitPropertyDeclaration(n); visitPropertyDeclaration(n);
} }
convention.checkForCallingConventionDefinitions(n, delegateCallingConventions);
break; break;
case ASSIGN: { case ASSIGN: {
Node lvalue = n.getFirstChild(); Node lvalue = n.getFirstChild();
Expand Down Expand Up @@ -1681,6 +1690,10 @@ private void visitCall(Node call) {
if (className != null) { if (className != null) {
applySingletonGetter(className); applySingletonGetter(className);
} }
DelegateRelationship delegateRelationship = convention.getDelegateRelationship(call);
if (delegateRelationship != null) {
applyDelegateRelationship(delegateRelationship);
}
} }


private void applySubclassRelationship(SubclassRelationship rel) { private void applySubclassRelationship(SubclassRelationship rel) {
Expand Down Expand Up @@ -1710,6 +1723,43 @@ private void applySingletonGetter(String className) {
} }
} }


private void applyDelegateRelationship(DelegateRelationship rel) {
RawNominalType delegateBase = findInScope(rel.delegateBase);
RawNominalType delegator = findInScope(rel.delegator);
RawNominalType delegateSuper = findInScope(convention.getDelegateSuperclassName());
if (delegator != null && delegateBase != null && delegateSuper != null) {
// Note: OTI also verified that getConstructor() was non-null on each of these, but since
// they're all coming from RawNominalTypes, there should be no way that can fail here.
JSType findDelegate =
new FunctionTypeBuilder(getCommonTypes())
.addReqFormal(getCommonTypes().getNativeType(U2U_CONSTRUCTOR_TYPE))
.addRetType(JSType.join(getCommonTypes().NULL, delegateBase.getInstanceAsJSType()))
.buildType();

RawNominalType delegateProxy = RawNominalType.makeClass(
getCommonTypes(),
delegateBase.getDefSite() /* defSite */,
delegateBase.getName() + "(Proxy)" /* name */,
null /* typeParameters */,
ObjectKind.UNRESTRICTED,
false /* isAbstract */);
nominaltypesByNode.put(new Node(null), delegateProxy);
delegateProxy.addSuperClass(delegateBase.getAsNominalType());
delegateProxy.setCtorFunction(
new FunctionTypeBuilder(getCommonTypes())
.addRetType(delegateProxy.getInstanceAsJSType())
.addNominalType(delegateProxy.getInstanceAsJSType())
.buildFunction());
convention.applyDelegateRelationship(
new NominalTypeBuilderNti(lateProps, delegateSuper),
new NominalTypeBuilderNti(lateProps, delegateBase),
new NominalTypeBuilderNti(lateProps, delegator),
delegateProxy.getInstanceAsJSType(),
findDelegate);
delegateProxies.add(new NominalTypeBuilderNti(lateProps, delegateProxy));
}
}

private RawNominalType findInScope(String qname) { private RawNominalType findInScope(String qname) {
return currentScope.getNominalType(QualifiedName.fromQualifiedString(qname)); return currentScope.getNominalType(QualifiedName.fromQualifiedString(qname));
} }
Expand Down
14 changes: 14 additions & 0 deletions src/com/google/javascript/jscomp/newtypes/FunctionType.java
Expand Up @@ -257,6 +257,20 @@ static Map<String, FunctionType> createInitialFunctionTypes(JSTypes commonTypes)
false)); false));
functions.put("TOP_FUNCTION", new FunctionType(commonTypes, false)); functions.put("TOP_FUNCTION", new FunctionType(commonTypes, false));
functions.put("LOOSE_TOP_FUNCTION", new FunctionType(commonTypes, true)); functions.put("LOOSE_TOP_FUNCTION", new FunctionType(commonTypes, true));
functions.put(
"U2U_CONSTRUCTOR",
FunctionType.normalized(
commonTypes,
null /* requiredFormals */,
null /* optionalFormals */,
commonTypes.UNKNOWN /* restFormals */,
commonTypes.UNKNOWN /* retType */,
commonTypes.UNKNOWN /* nominalType */,
null /* receiverType */,
null /* outerVars */,
null /* typeParameters */,
true /* isLoose */,
false /* isAbstract */));
return functions; return functions;
} }


Expand Down
2 changes: 1 addition & 1 deletion src/com/google/javascript/jscomp/newtypes/JSType.java
Expand Up @@ -1791,7 +1791,7 @@ public final boolean isVoidType() {
} }


@Override @Override
public final TypeI restrictByNotNullOrUndefined() { public final JSType restrictByNotNullOrUndefined() {
return this.removeType(this.commonTypes.NULL_OR_UNDEFINED); return this.removeType(this.commonTypes.NULL_OR_UNDEFINED);
} }


Expand Down
6 changes: 6 additions & 0 deletions src/com/google/javascript/jscomp/newtypes/JSTypes.java
Expand Up @@ -119,6 +119,9 @@ public final class JSTypes implements Serializable {
final FunctionType TOP_FUNCTION; final FunctionType TOP_FUNCTION;
@SuppressWarnings("ConstantField") @SuppressWarnings("ConstantField")
final FunctionType LOOSE_TOP_FUNCTION; final FunctionType LOOSE_TOP_FUNCTION;
// Constructor for unknown type.
@SuppressWarnings("ConstantField")
private final FunctionType U2U_CONSTRUCTOR;


@SuppressWarnings("ConstantField") @SuppressWarnings("ConstantField")
final Map<String, JSType> MAP_TO_UNKNOWN; final Map<String, JSType> MAP_TO_UNKNOWN;
Expand Down Expand Up @@ -203,6 +206,7 @@ private JSTypes(boolean inCompatibilityMode) {
this.BOTTOM_FUNCTION = checkNotNull(functions.get("BOTTOM_FUNCTION")); this.BOTTOM_FUNCTION = checkNotNull(functions.get("BOTTOM_FUNCTION"));
this.TOP_FUNCTION = checkNotNull(functions.get("TOP_FUNCTION")); this.TOP_FUNCTION = checkNotNull(functions.get("TOP_FUNCTION"));
this.LOOSE_TOP_FUNCTION = checkNotNull(functions.get("LOOSE_TOP_FUNCTION")); this.LOOSE_TOP_FUNCTION = checkNotNull(functions.get("LOOSE_TOP_FUNCTION"));
this.U2U_CONSTRUCTOR = checkNotNull(functions.get("U2U_CONSTRUCTOR"));
this.BOTTOM_PROPERTY_MAP = PersistentMap.of("_", Property.make(this.BOTTOM, this.BOTTOM)); this.BOTTOM_PROPERTY_MAP = PersistentMap.of("_", Property.make(this.BOTTOM, this.BOTTOM));


this.allowMethodsAsFunctions = inCompatibilityMode; this.allowMethodsAsFunctions = inCompatibilityMode;
Expand Down Expand Up @@ -516,6 +520,8 @@ public JSType getNativeType(JSTypeNative typeId) {
return getIteratorInstance(UNKNOWN); return getIteratorInstance(UNKNOWN);
case GENERATOR_TYPE: case GENERATOR_TYPE:
return getGeneratorInstance(UNKNOWN); return getGeneratorInstance(UNKNOWN);
case U2U_CONSTRUCTOR_TYPE:
return fromFunctionType(U2U_CONSTRUCTOR);
default: default:
throw new RuntimeException("Native type " + typeId.name() + " not found"); throw new RuntimeException("Native type " + typeId.name() + " not found");
} }
Expand Down
2 changes: 1 addition & 1 deletion src/com/google/javascript/jscomp/newtypes/ObjectType.java
Expand Up @@ -1661,7 +1661,7 @@ String toString(ToStringContext ctx) {
StringBuilder appendTo(StringBuilder builder, ToStringContext ctx) { StringBuilder appendTo(StringBuilder builder, ToStringContext ctx) {
// "Foo.prototype" is a valid type when appropriate. // "Foo.prototype" is a valid type when appropriate.
if (isPrototypeObject()) { if (isPrototypeObject()) {
return builder.append(getOwnerFunction().getThisType()).append(".prototype"); return builder.append(getOwnerFunction().getThisType().getDisplayName()).append(".prototype");
} }
// Annotations need simpler output that can be re-parsed. // Annotations need simpler output that can be re-parsed.
if (ctx.forAnnotation()) { if (ctx.forAnnotation()) {
Expand Down

0 comments on commit 01a7a90

Please sign in to comment.