Skip to content

Commit

Permalink
[NTI] Refactor CodingConvention.addSingletonGetter to share the same …
Browse files Browse the repository at this point in the history
…implementation for both OTI and NTI.

The main change is to introduce an ObjectTypeI.PropertyDeclarer interface that exposes a declareProperty method to add a property to a not-yet-frozen type.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=168755535
  • Loading branch information
shicks authored and lauraharker committed Sep 14, 2017
1 parent e788b7f commit 1a8bb56
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 55 deletions.
16 changes: 7 additions & 9 deletions src/com/google/javascript/jscomp/ChromeCodingConvention.java
Expand Up @@ -19,9 +19,9 @@
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.errorprone.annotations.Immutable; import com.google.errorprone.annotations.Immutable;
import com.google.javascript.jscomp.ClosureCodingConvention.AssertInstanceofSpec; import com.google.javascript.jscomp.ClosureCodingConvention.AssertInstanceofSpec;
import com.google.javascript.rhino.FunctionTypeI;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.jstype.FunctionType; import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.jstype.ObjectType;
import java.util.Collection; import java.util.Collection;


/** /**
Expand Down Expand Up @@ -53,13 +53,11 @@ public String getSingletonGetterClassName(Node callNode) {
} }


@Override @Override
public void applySingletonGetterOld(FunctionType functionType, public void applySingletonGetter(ObjectTypeI.PropertyDeclarer declarer,
FunctionType getterType, ObjectType objectType) { FunctionTypeI functionType, FunctionTypeI getterType, ObjectTypeI objectType) {
super.applySingletonGetterOld(functionType, getterType, objectType); super.applySingletonGetter(declarer, functionType, getterType, objectType);
functionType.defineDeclaredProperty("getInstance", getterType, declarer.declareProperty(functionType, "getInstance", getterType, functionType.getSource());
functionType.getSource()); declarer.declareProperty(functionType, "instance_", objectType, functionType.getSource());
functionType.defineDeclaredProperty("instance_", objectType,
functionType.getSource());
} }


@Override @Override
Expand Down
22 changes: 7 additions & 15 deletions src/com/google/javascript/jscomp/ClosureCodingConvention.java
Expand Up @@ -25,13 +25,14 @@
import com.google.javascript.jscomp.newtypes.DeclaredTypeRegistry; import com.google.javascript.jscomp.newtypes.DeclaredTypeRegistry;
import com.google.javascript.jscomp.newtypes.JSType; import com.google.javascript.jscomp.newtypes.JSType;
import com.google.javascript.jscomp.newtypes.QualifiedName; import com.google.javascript.jscomp.newtypes.QualifiedName;
import com.google.javascript.jscomp.newtypes.RawNominalType; import com.google.javascript.rhino.FunctionTypeI;
import com.google.javascript.rhino.IR; import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.ObjectTypeI.PropertyDeclarer;
import com.google.javascript.rhino.jstype.FunctionType; import com.google.javascript.rhino.jstype.FunctionType;
import com.google.javascript.rhino.jstype.JSTypeNative; import com.google.javascript.rhino.jstype.JSTypeNative;
import com.google.javascript.rhino.jstype.JSTypeRegistry; import com.google.javascript.rhino.jstype.JSTypeRegistry;
import com.google.javascript.rhino.jstype.ObjectType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
Expand Down Expand Up @@ -323,19 +324,10 @@ public String getSingletonGetterClassName(Node callNode) {
} }


@Override @Override
public void applySingletonGetterOld(FunctionType functionType, public void applySingletonGetter(PropertyDeclarer declarer,
FunctionType getterType, ObjectType objectType) { FunctionTypeI functionType, FunctionTypeI getterType, ObjectTypeI objectType) {
functionType.defineDeclaredProperty("getInstance", getterType, declarer.declareProperty(functionType, "getInstance", getterType, functionType.getSource());
functionType.getSource()); declarer.declareProperty(functionType, "instance_", objectType, functionType.getSource());
functionType.defineDeclaredProperty("instance_", objectType,
functionType.getSource());
}

@Override
public void applySingletonGetterNew(
RawNominalType rawType, JSType getInstanceType, JSType instanceType) {
rawType.addCtorProperty("getInstance", null, getInstanceType, true);
rawType.addCtorProperty("instance_", null, instanceType, true);
} }


@Override @Override
Expand Down
14 changes: 8 additions & 6 deletions src/com/google/javascript/jscomp/CodingConvention.java
Expand Up @@ -19,8 +19,10 @@
import com.google.errorprone.annotations.Immutable; import com.google.errorprone.annotations.Immutable;
import com.google.javascript.jscomp.newtypes.DeclaredTypeRegistry; import com.google.javascript.jscomp.newtypes.DeclaredTypeRegistry;
import com.google.javascript.jscomp.newtypes.JSType; import com.google.javascript.jscomp.newtypes.JSType;
import com.google.javascript.jscomp.newtypes.RawNominalType; import com.google.javascript.rhino.FunctionTypeI;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.ObjectTypeI.PropertyDeclarer;
import com.google.javascript.rhino.StaticSourceFile; import com.google.javascript.rhino.StaticSourceFile;
import com.google.javascript.rhino.jstype.FunctionType; import com.google.javascript.rhino.jstype.FunctionType;
import com.google.javascript.rhino.jstype.JSTypeNative; import com.google.javascript.rhino.jstype.JSTypeNative;
Expand Down Expand Up @@ -241,11 +243,11 @@ public void applySubclassRelationship(FunctionType parentCtor,
* In many JS libraries, the function that adds a singleton getter to a class * In many JS libraries, the function that adds a singleton getter to a class
* adds properties to the class. * adds properties to the class.
*/ */
public void applySingletonGetterOld(FunctionType functionType, public void applySingletonGetter(
FunctionType getterType, ObjectType objectType); PropertyDeclarer declarer,

FunctionTypeI functionType,
public void applySingletonGetterNew( FunctionTypeI getterType,
RawNominalType rawType, JSType getInstanceType, JSType instanceType); ObjectTypeI objectType);


/** /**
* @return Whether the function is inlinable by convention. * @return Whether the function is inlinable by convention.
Expand Down
29 changes: 9 additions & 20 deletions src/com/google/javascript/jscomp/CodingConventions.java
Expand Up @@ -20,9 +20,10 @@


import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.Immutable; import com.google.errorprone.annotations.Immutable;
import com.google.javascript.jscomp.newtypes.JSType; import com.google.javascript.rhino.FunctionTypeI;
import com.google.javascript.jscomp.newtypes.RawNominalType;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.ObjectTypeI.PropertyDeclarer;
import com.google.javascript.rhino.StaticSourceFile; import com.google.javascript.rhino.StaticSourceFile;
import com.google.javascript.rhino.jstype.FunctionType; import com.google.javascript.rhino.jstype.FunctionType;
import com.google.javascript.rhino.jstype.JSTypeRegistry; import com.google.javascript.rhino.jstype.JSTypeRegistry;
Expand Down Expand Up @@ -216,16 +217,9 @@ public String getSingletonGetterClassName(Node callNode) {
} }


@Override @Override
public void applySingletonGetterOld(FunctionType functionType, public void applySingletonGetter(PropertyDeclarer declarer,
FunctionType getterType, ObjectType objectType) { FunctionTypeI functionType, FunctionTypeI getterType, ObjectTypeI objectType) {
nextConvention.applySingletonGetterOld( nextConvention.applySingletonGetter(declarer, functionType, getterType, objectType);
functionType, getterType, objectType);
}

@Override
public void applySingletonGetterNew(
RawNominalType rawType, JSType getInstanceType, JSType instanceType) {
nextConvention.applySingletonGetterNew(rawType, getInstanceType, instanceType);
} }


@Override @Override
Expand Down Expand Up @@ -480,14 +474,9 @@ public String getSingletonGetterClassName(Node callNode) {
} }


@Override @Override
public void applySingletonGetterOld(FunctionType functionType, public void applySingletonGetter(
FunctionType getterType, ObjectType objectType) { PropertyDeclarer declarer, FunctionTypeI functionType,
// do nothing. FunctionTypeI getterType, ObjectTypeI objectType) {
}

@Override
public void applySingletonGetterNew(
RawNominalType rawType, JSType getInstanceType, JSType instanceType) {
// do nothing. // do nothing.
} }


Expand Down
17 changes: 14 additions & 3 deletions src/com/google/javascript/jscomp/GlobalTypeInfoCollector.java
Expand Up @@ -43,6 +43,7 @@
import com.google.javascript.jscomp.newtypes.Namespace; import com.google.javascript.jscomp.newtypes.Namespace;
import com.google.javascript.jscomp.newtypes.NominalType; import com.google.javascript.jscomp.newtypes.NominalType;
import com.google.javascript.jscomp.newtypes.ObjectKind; import com.google.javascript.jscomp.newtypes.ObjectKind;
import com.google.javascript.jscomp.newtypes.PropertyDeclarer;
import com.google.javascript.jscomp.newtypes.QualifiedName; import com.google.javascript.jscomp.newtypes.QualifiedName;
import com.google.javascript.jscomp.newtypes.RawNominalType; import com.google.javascript.jscomp.newtypes.RawNominalType;
import com.google.javascript.jscomp.newtypes.Typedef; import com.google.javascript.jscomp.newtypes.Typedef;
Expand Down Expand Up @@ -286,6 +287,8 @@ public class GlobalTypeInfoCollector implements CompilerPass {
private static final String WINDOW_INSTANCE = "window"; private static final String WINDOW_INSTANCE = "window";
private static final String WINDOW_CLASS = "Window"; private static final String WINDOW_CLASS = "Window";


private static final PropertyDeclarer PROPERTY_DECLARER = new PropertyDeclarer();

private DefaultNameGenerator funNameGen; private DefaultNameGenerator funNameGen;
// Only for original definitions, not for aliased constructors // Only for original definitions, not for aliased constructors
private Map<Node, RawNominalType> nominaltypesByNode = new LinkedHashMap<>(); private Map<Node, RawNominalType> nominaltypesByNode = new LinkedHashMap<>();
Expand Down Expand Up @@ -1562,18 +1565,26 @@ private void visitObjectLit(Node objLitNode, Node parent) {
} }


private void visitCall(Node call) { private void visitCall(Node call) {
// Check various coding conventions to see if any additional handling is needed.
String className = convention.getSingletonGetterClassName(call); String className = convention.getSingletonGetterClassName(call);
if (className == null) { if (className != null) {
return; applySingletonGetter(className);
} }
}

private void applySingletonGetter(String className) {
QualifiedName qname = QualifiedName.fromQualifiedString(className); QualifiedName qname = QualifiedName.fromQualifiedString(className);
RawNominalType rawType = currentScope.getNominalType(qname); RawNominalType rawType = currentScope.getNominalType(qname);
if (rawType != null) { if (rawType != null) {
JSType instanceType = rawType.getInstanceAsJSType(); JSType instanceType = rawType.getInstanceAsJSType();
FunctionType getInstanceFunType = FunctionType getInstanceFunType =
new FunctionTypeBuilder(getCommonTypes()).addRetType(instanceType).buildFunction(); new FunctionTypeBuilder(getCommonTypes()).addRetType(instanceType).buildFunction();
JSType getInstanceType = getCommonTypes().fromFunctionType(getInstanceFunType); JSType getInstanceType = getCommonTypes().fromFunctionType(getInstanceFunType);
convention.applySingletonGetterNew(rawType, getInstanceType, instanceType); convention.applySingletonGetter(
PROPERTY_DECLARER,
getCommonTypes().fromFunctionType(rawType.getConstructorFunction()),
getInstanceType,
instanceType);
} }
} }


Expand Down
6 changes: 5 additions & 1 deletion src/com/google/javascript/jscomp/TypedScopeCreator.java
Expand Up @@ -73,6 +73,7 @@
import com.google.javascript.rhino.jstype.JSTypeRegistry; import com.google.javascript.rhino.jstype.JSTypeRegistry;
import com.google.javascript.rhino.jstype.ObjectType; import com.google.javascript.rhino.jstype.ObjectType;
import com.google.javascript.rhino.jstype.Property; import com.google.javascript.rhino.jstype.Property;
import com.google.javascript.rhino.jstype.PropertyDeclarer;
import com.google.javascript.rhino.jstype.TemplateType; import com.google.javascript.rhino.jstype.TemplateType;
import com.google.javascript.rhino.jstype.TemplateTypeMap; import com.google.javascript.rhino.jstype.TemplateTypeMap;
import com.google.javascript.rhino.jstype.TemplateTypeMapReplacer; import com.google.javascript.rhino.jstype.TemplateTypeMapReplacer;
Expand Down Expand Up @@ -149,6 +150,8 @@ final class TypedScopeCreator implements ScopeCreator {
UNKNOWN_LENDS, UNKNOWN_LENDS,
LENDS_ON_NON_OBJECT); LENDS_ON_NON_OBJECT);


private static final PropertyDeclarer PROPERTY_DECLARER = new PropertyDeclarer();

private final AbstractCompiler compiler; private final AbstractCompiler compiler;
private final ErrorReporter typeParsingErrorReporter; private final ErrorReporter typeParsingErrorReporter;
private final TypeValidator validator; private final TypeValidator validator;
Expand Down Expand Up @@ -1514,7 +1517,8 @@ private void checkForClassDefiningCalls(Node n) {


if (functionType != null) { if (functionType != null) {
FunctionType getterType = typeRegistry.createFunctionType(objectType); FunctionType getterType = typeRegistry.createFunctionType(objectType);
codingConvention.applySingletonGetterOld(functionType, getterType, objectType); codingConvention.applySingletonGetter(
PROPERTY_DECLARER, functionType, getterType, objectType);
} }
} }
} }
Expand Down
53 changes: 53 additions & 0 deletions src/com/google/javascript/jscomp/newtypes/PropertyDeclarer.java
@@ -0,0 +1,53 @@
/*
* Copyright 2017 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.javascript.jscomp.newtypes;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.javascript.rhino.FunctionTypeI;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.TypeI;

/**
* NTI implementation of ObjectTypeI.PropertyDeclarer.
*/
public final class PropertyDeclarer implements ObjectTypeI.PropertyDeclarer {
@Override
public void declareProperty(ObjectTypeI object, String property, TypeI type, Node defSite) {
checkArgument(object instanceof JSType);
checkArgument(type instanceof JSType);
FunctionTypeI owner = object.getOwnerFunction();
if (owner != null) {
object = owner;
}
boolean ctor = object.isConstructor();
if (ctor) {
object = ((FunctionTypeI) object).getInstanceType();
}
NominalType nt = ((JSType) object).getNominalTypeIfSingletonObj();
checkArgument(nt != null);
RawNominalType rt = nt.getRawNominalType();
if (owner != null) {
rt.addProtoProperty(property, defSite, (JSType) type, true);
} else if (ctor) {
rt.addCtorProperty(property, defSite, (JSType) type, true);
} else {
rt.addInstanceProperty(property, defSite, (JSType) type, true);
}
}
}
2 changes: 1 addition & 1 deletion src/com/google/javascript/rhino/FunctionTypeI.java
Expand Up @@ -46,7 +46,7 @@
* @author blickly@google.com (Ben Lickly) * @author blickly@google.com (Ben Lickly)
* @author dimvar@google.com (Dimitris Vardoulakis) * @author dimvar@google.com (Dimitris Vardoulakis)
*/ */
public interface FunctionTypeI extends TypeI { public interface FunctionTypeI extends ObjectTypeI {
/** /**
* Creates a new function type B based on the original function type A. * Creates a new function type B based on the original function type A.
* Takes the receiver type (this type) of A and makes it the first * Takes the receiver type (this type) of A and makes it the first
Expand Down
6 changes: 6 additions & 0 deletions src/com/google/javascript/rhino/ObjectTypeI.java
Expand Up @@ -176,4 +176,10 @@ public interface ObjectTypeI extends TypeI {
* Returns a set of properties defined or inferred on this type or any of its supertypes. * Returns a set of properties defined or inferred on this type or any of its supertypes.
*/ */
Set<String> getPropertyNames(); Set<String> getPropertyNames();

/** Interface for declaring properties on object types while they are being built. */
interface PropertyDeclarer {
/** Declares the given property on the given object type. */
void declareProperty(ObjectTypeI object, String property, TypeI type, Node defSite);
}
} }
58 changes: 58 additions & 0 deletions src/com/google/javascript/rhino/jstype/PropertyDeclarer.java
@@ -0,0 +1,58 @@
/*
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Bob Jervis
* Google Inc.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

package com.google.javascript.rhino.jstype;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.ObjectTypeI;
import com.google.javascript.rhino.TypeI;

/**
* OTI implementation of ObjectTypeI.PropertyDeclarer.
*/
public final class PropertyDeclarer implements ObjectTypeI.PropertyDeclarer {
@Override
public void declareProperty(ObjectTypeI object, String property, TypeI type, Node defSite) {
checkArgument(object instanceof ObjectType);
checkArgument(type instanceof JSType);
((ObjectType) object).defineDeclaredProperty(property, (JSType) type, defSite);
}
}

0 comments on commit 1a8bb56

Please sign in to comment.