public final class TypeCheck extends java.lang.Object implements NodeTraversal.Callback, CompilerPass
Checks the types of JS expressions against any declared type information.
Modifier and Type | Class and Description |
---|---|
private static class |
TypeCheck.SuggestionPair |
Constructor and Description |
---|
TypeCheck(AbstractCompiler compiler,
ReverseAbstractInterpreter reverseInterpreter,
JSTypeRegistry typeRegistry) |
TypeCheck(AbstractCompiler compiler,
ReverseAbstractInterpreter reverseInterpreter,
JSTypeRegistry typeRegistry,
CheckLevel reportMissingOverride) |
TypeCheck(AbstractCompiler compiler,
ReverseAbstractInterpreter reverseInterpreter,
JSTypeRegistry typeRegistry,
TypedScope topScope,
MemoizedScopeCreator scopeCreator,
CheckLevel reportMissingOverride) |
Modifier and Type | Method and Description |
---|---|
(package private) void |
check(Node node,
boolean externs) |
private void |
checkCallConventions(NodeTraversal t,
Node n)
Validate class-defining calls.
|
private void |
checkDeclaredPropertyInheritance(NodeTraversal t,
Node n,
FunctionType ctorType,
java.lang.String propertyName,
JSDocInfo info,
JSType propertyType)
Given a constructor type and a property name, check that the property has
the JSDoc annotation @override iff the property is declared on a
superclass.
|
private void |
checkEnumAlias(NodeTraversal t,
JSDocInfo declInfo,
Node value)
Checks enum aliases.
|
private void |
checkInterfaceConflictProperties(NodeTraversal t,
Node n,
java.lang.String functionName,
java.util.Map<java.lang.String,ObjectType> properties,
java.util.Map<java.lang.String,ObjectType> currentProperties,
ObjectType interfaceType)
Check whether there's any property conflict for for a particular super
interface
|
private void |
checkJsdocInfoContainsObjectWithBadKey(NodeTraversal t,
Node n)
Checks if current node contains js docs and checks all types specified in the js doc whether
they have Objects with potentially invalid keys.
|
private void |
checkPropCreation(NodeTraversal t,
Node lvalue) |
private void |
checkPropertyAccess(JSType childType,
java.lang.String propName,
NodeTraversal t,
Node n)
Emit a warning if we can prove that a property cannot possibly be
defined on an object.
|
private void |
checkPropertyAccessHelper(JSType objectType,
java.lang.String propName,
NodeTraversal t,
Node n) |
private void |
checkPropertyInheritanceOnGetpropAssign(NodeTraversal t,
Node assign,
Node object,
java.lang.String property,
JSDocInfo info,
JSType propertyType) |
private void |
checkPropertyInheritanceOnPrototypeLitKey(NodeTraversal t,
Node key,
java.lang.String propertyName,
ObjectType type) |
private void |
checkTypeContainsObjectWithBadKey(NodeTraversal t,
Node n,
JSTypeExpression type) |
private void |
checkTypeofString(NodeTraversal t,
Node n,
java.lang.String s) |
private boolean |
classHasToString(ObjectType type)
Checks whether class has overridden toString() method.
|
private void |
doPercentTypedAccounting(NodeTraversal t,
Node n)
Counts the given node in the typed statistics.
|
private void |
ensureTyped(NodeTraversal t,
Node n)
Ensure that the given node has a type.
|
private void |
ensureTyped(NodeTraversal t,
Node n,
JSType type)
Enforces type casts, and ensures the node is typed.
|
private void |
ensureTyped(NodeTraversal t,
Node n,
JSTypeNative type) |
private JSType |
findObjectWithNonStringifiableKey(JSType type)
Checks whether type (or one of its component if is composed type like union or templatized
type) has Object with non-stringifiable key.
|
private static TypeCheck.SuggestionPair |
getClosestPropertySuggestion(JSType objectType,
java.lang.String propName) |
private JSType |
getJSType(Node n)
This method gets the JSType from the Node argument and verifies that it is
present.
|
private JSType |
getNativeType(JSTypeNative typeId) |
(package private) static JSType |
getObjectLitKeyTypeFromValueType(Node key,
JSType valueType) |
(package private) double |
getTypedPercent()
Returns the percentage of nodes typed by the type checker.
|
private static boolean |
hasUnknownOrEmptySupertype(FunctionType ctor)
Given a constructor or an interface type, find out whether the unknown
type is a supertype of the current type.
|
private boolean |
isObjectTypeWithNonStringifiableKey(JSType type)
Checks whether current type is Object type with non-stringifable key.
|
private boolean |
isStringifiable(JSType type)
Checks whether type is stringifiable.
|
void |
process(Node externsRoot,
Node jsRoot)
Main entry point for this phase of processing.
|
TypedScope |
processForTesting(Node externsRoot,
Node jsRoot)
Main entry point of this phase for testing code.
|
private static boolean |
propertyIsImplicitCast(ObjectType type,
java.lang.String prop)
Returns true if any type in the chain has an implicitCast annotation for
the given property.
|
private void |
report(NodeTraversal t,
Node n,
DiagnosticType diagnosticType,
java.lang.String... arguments) |
(package private) TypeCheck |
reportMissingProperties(boolean report)
Turn on the missing property check.
|
boolean |
shouldTraverse(NodeTraversal t,
Node n,
Node parent)
Visits a node in pre order (before visiting its children) and decides
whether this node's children should be traversed.
|
void |
visit(NodeTraversal t,
Node n,
Node parent)
This is the meat of the type checking.
|
private void |
visitAssign(NodeTraversal t,
Node assign)
Visits an assignment
lvalue = rvalue . |
private void |
visitBinaryOperator(int op,
NodeTraversal t,
Node n)
This function unifies the type checking involved in the core binary
operators and the corresponding assignment operators.
|
private void |
visitCall(NodeTraversal t,
Node n)
Visits a CALL node.
|
private void |
visitFunction(NodeTraversal t,
Node n)
Visits a
Token.FUNCTION node. |
private void |
visitGetElem(NodeTraversal t,
Node n)
Visits a GETELEM node.
|
private void |
visitGetProp(NodeTraversal t,
Node n,
Node parent)
Visits a GETPROP node.
|
private void |
visitInterfaceGetprop(NodeTraversal t,
Node assign,
Node object,
java.lang.String property,
Node lvalue,
Node rvalue)
Visits an ASSIGN node for cases such as
|
(package private) boolean |
visitName(NodeTraversal t,
Node n,
Node parent)
Visits a NAME node.
|
private void |
visitNew(NodeTraversal t,
Node n)
Visits a NEW node.
|
private void |
visitObjLitKey(NodeTraversal t,
Node key,
Node objlit,
JSType litType)
Visits an object literal field definition
key : value . |
private void |
visitParameterList(NodeTraversal t,
Node call,
FunctionType functionType)
Visits the parameters of a CALL or a NEW node.
|
private void |
visitReturn(NodeTraversal t,
Node n)
Visits a RETURN node.
|
private void |
visitVar(NodeTraversal t,
Node n)
Visits a VAR node.
|
static final DiagnosticType UNEXPECTED_TOKEN
protected static final java.lang.String OVERRIDING_PROTOTYPE_WITH_NON_OBJECT
static final DiagnosticType DETERMINISTIC_TEST
static final DiagnosticType INEXISTENT_ENUM_ELEMENT
public static final DiagnosticType INEXISTENT_PROPERTY
static final DiagnosticType POSSIBLE_INEXISTENT_PROPERTY
static final DiagnosticType INEXISTENT_PROPERTY_WITH_SUGGESTION
protected static final DiagnosticType NOT_A_CONSTRUCTOR
static final DiagnosticType BIT_OPERATION
static final DiagnosticType NOT_CALLABLE
static final DiagnosticType CONSTRUCTOR_NOT_CALLABLE
static final DiagnosticType FUNCTION_MASKS_VARIABLE
static final DiagnosticType MULTIPLE_VAR_DEF
static final DiagnosticType ENUM_DUP
static final DiagnosticType INVALID_INTERFACE_MEMBER_DECLARATION
static final DiagnosticType INTERFACE_METHOD_NOT_EMPTY
static final DiagnosticType CONFLICTING_EXTENDED_TYPE
static final DiagnosticType INTERFACE_EXTENDS_LOOP
static final DiagnosticType CONFLICTING_IMPLEMENTED_TYPE
static final DiagnosticType BAD_IMPLEMENTED_TYPE
static final DiagnosticType HIDDEN_SUPERCLASS_PROPERTY
static final DiagnosticType HIDDEN_INTERFACE_PROPERTY
static final DiagnosticType HIDDEN_SUPERCLASS_PROPERTY_MISMATCH
static final DiagnosticType UNKNOWN_OVERRIDE
static final DiagnosticType INTERFACE_METHOD_OVERRIDE
static final DiagnosticType UNKNOWN_EXPR_TYPE
static final DiagnosticType UNRESOLVED_TYPE
static final DiagnosticType WRONG_ARGUMENT_COUNT
static final DiagnosticType ILLEGAL_IMPLICIT_CAST
static final DiagnosticType INCOMPATIBLE_EXTENDED_PROPERTY_TYPE
static final DiagnosticType EXPECTED_THIS_TYPE
static final DiagnosticType IN_USED_WITH_STRUCT
static final DiagnosticType ILLEGAL_PROPERTY_CREATION
static final DiagnosticType ILLEGAL_OBJLIT_KEY
static final DiagnosticType NON_STRINGIFIABLE_OBJECT_KEY
static final DiagnosticGroup ALL_DIAGNOSTICS
private final AbstractCompiler compiler
private final TypeValidator validator
private final ReverseAbstractInterpreter reverseInterpreter
private final JSTypeRegistry typeRegistry
private TypedScope topScope
private MemoizedScopeCreator scopeCreator
private final CheckLevel reportMissingOverride
private final boolean reportUnknownTypes
private boolean reportMissingProperties
private InferJSDocInfo inferJSDocInfo
private int typedCount
private int nullCount
private int unknownCount
private boolean inExterns
public TypeCheck(AbstractCompiler compiler, ReverseAbstractInterpreter reverseInterpreter, JSTypeRegistry typeRegistry, TypedScope topScope, MemoizedScopeCreator scopeCreator, CheckLevel reportMissingOverride)
public TypeCheck(AbstractCompiler compiler, ReverseAbstractInterpreter reverseInterpreter, JSTypeRegistry typeRegistry, CheckLevel reportMissingOverride)
TypeCheck(AbstractCompiler compiler, ReverseAbstractInterpreter reverseInterpreter, JSTypeRegistry typeRegistry)
TypeCheck reportMissingProperties(boolean report)
public void process(Node externsRoot, Node jsRoot)
process
in interface CompilerPass
externsRoot
- The root of the externs parse tree.jsRoot
- The root of the input parse tree to be checked.public TypedScope processForTesting(Node externsRoot, Node jsRoot)
void check(Node node, boolean externs)
private void report(NodeTraversal t, Node n, DiagnosticType diagnosticType, java.lang.String... arguments)
public boolean shouldTraverse(NodeTraversal t, Node n, Node parent)
NodeTraversal.Callback
Visits a node in pre order (before visiting its children) and decides
whether this node's children should be traversed. If children are
traversed, they will be visited by
NodeTraversal.Callback.visit(NodeTraversal, Node, Node)
in postorder.
Implementations can have side effects (e.g. modifying the parse tree).
shouldTraverse
in interface NodeTraversal.Callback
public void visit(NodeTraversal t, Node n, Node parent)
visit
in interface NodeTraversal.Callback
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.parent
- The parent of the node n.private void checkTypeofString(NodeTraversal t, Node n, java.lang.String s)
private void doPercentTypedAccounting(NodeTraversal t, Node n)
n
- a node that should be typedprivate void visitAssign(NodeTraversal t, Node assign)
lvalue = rvalue
. If the
lvalue
is a prototype modification, we change the schema
of the object type it is referring to.t
- the traversalassign
- the assign node
(assign.isAssign()
is an implicit invariant)private void checkPropCreation(NodeTraversal t, Node lvalue)
private void checkPropertyInheritanceOnGetpropAssign(NodeTraversal t, Node assign, Node object, java.lang.String property, JSDocInfo info, JSType propertyType)
private void checkPropertyInheritanceOnPrototypeLitKey(NodeTraversal t, Node key, java.lang.String propertyName, ObjectType type)
private void visitObjLitKey(NodeTraversal t, Node key, Node objlit, JSType litType)
key : value
.
If the lvalue
is a prototype modification, we change the
schema of the object type it is referring to.t
- the traversalkey
- the assign nodeprivate static boolean propertyIsImplicitCast(ObjectType type, java.lang.String prop)
private void checkDeclaredPropertyInheritance(NodeTraversal t, Node n, FunctionType ctorType, java.lang.String propertyName, JSDocInfo info, JSType propertyType)
private static boolean hasUnknownOrEmptySupertype(FunctionType ctor)
static JSType getObjectLitKeyTypeFromValueType(Node key, JSType valueType)
key
- A OBJECTLIT key node.private void visitInterfaceGetprop(NodeTraversal t, Node assign, Node object, java.lang.String property, Node lvalue, Node rvalue)
interface.property2.property = ...;
boolean visitName(NodeTraversal t, Node n, Node parent)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.parent
- The parent of the node n.private void visitGetProp(NodeTraversal t, Node n, Node parent)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.parent
- The parent of n
private void checkPropertyAccess(JSType childType, java.lang.String propName, NodeTraversal t, Node n)
private void checkPropertyAccessHelper(JSType objectType, java.lang.String propName, NodeTraversal t, Node n)
private static TypeCheck.SuggestionPair getClosestPropertySuggestion(JSType objectType, java.lang.String propName)
private void visitGetElem(NodeTraversal t, Node n)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.private void visitVar(NodeTraversal t, Node n)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.private void visitNew(NodeTraversal t, Node n)
private void checkInterfaceConflictProperties(NodeTraversal t, Node n, java.lang.String functionName, java.util.Map<java.lang.String,ObjectType> properties, java.util.Map<java.lang.String,ObjectType> currentProperties, ObjectType interfaceType)
t
- The node traversal object that supplies contextn
- The node being visitedfunctionName
- The function name being checkedproperties
- The property names in the super interfaces that have
been visitedcurrentProperties
- The property names in the super interface
that have been visitedinterfaceType
- The super interface that is being visitedprivate void visitFunction(NodeTraversal t, Node n)
Token.FUNCTION
node.t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.private void checkCallConventions(NodeTraversal t, Node n)
private void visitCall(NodeTraversal t, Node n)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.private void visitParameterList(NodeTraversal t, Node call, FunctionType functionType)
private void visitReturn(NodeTraversal t, Node n)
t
- The node traversal object that supplies context, such as the
scope chain to use in name lookups as well as error reporting.n
- The node being visited.private void visitBinaryOperator(int op, NodeTraversal t, Node n)
op
- The operator.t
- The traversal object, needed to report errors.n
- The node being checked.private void checkEnumAlias(NodeTraversal t, JSDocInfo declInfo, Node value)
Checks enum aliases.
We verify that the enum element type of the enum used for initialization is a subtype of the enum element type of the enum the value is being copied in.
Example:
var myEnum = myOtherEnum;
Enum aliases are irregular, so we need special code for this :(
value
- the value used for initialization of the enumprivate JSType getJSType(Node n)
private void ensureTyped(NodeTraversal t, Node n)
private void ensureTyped(NodeTraversal t, Node n, JSTypeNative type)
private void ensureTyped(NodeTraversal t, Node n, JSType type)
t
- The traversal object needed to report errors.n
- The node getting a type assigned to it.type
- The type to be assigned.double getTypedPercent()
private JSType getNativeType(JSTypeNative typeId)
private void checkJsdocInfoContainsObjectWithBadKey(NodeTraversal t, Node n)
Object<!Object, number>
. If such type is found, a warning is reported for the current node.private void checkTypeContainsObjectWithBadKey(NodeTraversal t, Node n, JSTypeExpression type)
private boolean isStringifiable(JSType type)
private boolean isObjectTypeWithNonStringifiableKey(JSType type)
private JSType findObjectWithNonStringifiableKey(JSType type)
Object.<!Object, number>
.private boolean classHasToString(ObjectType type)