com.google.javascript.rhino.jstype.StaticSlot Java Examples

The following examples show how to use com.google.javascript.rhino.jstype.StaticSlot. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LinkedFlowScope.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Iterate through all the linked flow scopes before this one.
 * If there's one and only one slot defined between this scope
 * and the blind scope, return it.
 */
@Override
public StaticSlot<JSType> findUniqueRefinedSlot(FlowScope blindScope) {
  StaticSlot<JSType> result = null;

  for (LinkedFlowScope currentScope = this;
       currentScope != blindScope;
       currentScope = currentScope.parent) {
    for (LinkedFlowSlot currentSlot = currentScope.lastSlot;
         currentSlot != null &&
         (currentScope.parent == null ||
          currentScope.parent.lastSlot != currentSlot);
         currentSlot = currentSlot.parent) {
      if (result == null) {
        result = currentSlot;
      } else if (!currentSlot.getName().equals(result.getName())) {
        return null;
      }
    }
  }

  return result;
}
 
Example #2
Source File: SymbolTable.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
/** Helper for addSymbolsFrom, to determine the best declaration spot. */
private <S extends StaticSlot<JSType>, R extends StaticReference<JSType>>
StaticReference<JSType> findBestDeclToAdd(
    StaticSymbolTable<S, R> otherSymbolTable, S slot) {
  StaticReference<JSType> decl = slot.getDeclaration();
  if (isGoodRefToAdd(decl)) {
    return decl;
  }

  for (R ref : otherSymbolTable.getReferences(slot)) {
    if (isGoodRefToAdd(ref)) {
      return ref;
    }
  }

  return null;
}
 
Example #3
Source File: SemanticReverseAbstractInterpreter.java    From astor with GNU General Public License v2.0 6 votes vote down vote up
private FlowScope caseAndOrMaybeShortCircuiting(Node left, Node right,
    FlowScope blindScope, boolean condition) {
  FlowScope leftScope = firstPreciserScopeKnowingConditionOutcome(
      left, blindScope, !condition);
  StaticSlot<JSType> leftVar = leftScope.findUniqueRefinedSlot(blindScope);
  if (leftVar == null) {
    return blindScope;
  }
  FlowScope rightScope = firstPreciserScopeKnowingConditionOutcome(
      left, blindScope, condition);
  rightScope = firstPreciserScopeKnowingConditionOutcome(
      right, rightScope, !condition);
  StaticSlot<JSType> rightVar = rightScope.findUniqueRefinedSlot(blindScope);
  if (rightVar == null || !leftVar.getName().equals(rightVar.getName())) {
    return blindScope;
  }
  JSType type = leftVar.getType().getLeastSupertype(rightVar.getType());
  FlowScope informed = blindScope.createChildFlowScope();
  informed.inferSlotType(leftVar.getName(), type);
  return informed;
}
 
Example #4
Source File: Closure_6_TypeValidator_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Expect that the property in an interface that this type implements is
 * implemented and correctly typed.
 */
private void expectInterfaceProperty(NodeTraversal t, Node n,
    ObjectType instance, ObjectType implementedInterface, String prop) {
  StaticSlot<JSType> propSlot = instance.getSlot(prop);
  if (propSlot == null) {
    // Not implemented
    String sourceName = n.getSourceFileName();
    sourceName = sourceName == null ? "" : sourceName;
    registerMismatch(instance, implementedInterface,
        report(JSError.make(sourceName, n,
        INTERFACE_METHOD_NOT_IMPLEMENTED,
        prop, implementedInterface.toString(), instance.toString())));
  } else {
    Node propNode = propSlot.getDeclaration() == null ?
        null : propSlot.getDeclaration().getNode();

    // Fall back on the constructor node if we can't find a node for the
    // property.
    propNode = propNode == null ? n : propNode;

    JSType found = propSlot.getType();
    JSType required
        = implementedInterface.getImplicitPrototype().getPropertyType(prop);
    found = found.restrictByNotNullOrUndefined();
    required = required.restrictByNotNullOrUndefined();
    if (!found.canAssignTo(required)) {
      // Implemented, but not correctly typed
      FunctionType constructor =
          implementedInterface.toObjectType().getConstructor();
      registerMismatch(found, required, report(t.makeError(propNode,
          HIDDEN_INTERFACE_PROPERTY_MISMATCH, prop,
          constructor.getTopMostDefiningType(prop).toString(),
          required.toString(), found.toString())));
    }
  }
}
 
Example #5
Source File: Closure_35_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseName(Node n, FlowScope scope) {
  String varName = n.getString();
  Node value = n.getFirstChild();
  JSType type = n.getJSType();
  if (value != null) {
    scope = traverse(value, scope);
    updateScopeForTypeChange(scope, n, n.getJSType() /* could be null */,
        getJSType(value));
    return scope;
  } else {
    StaticSlot<JSType> var = scope.getSlot(varName);
    if (var != null) {
      // There are two situations where we don't want to use type information
      // from the scope, even if we have it.

      // 1) The var is escaped in a weird way, e.g.,
      // function f() { var x = 3; function g() { x = null } (x); }
      boolean isInferred = var.isTypeInferred();
      boolean unflowable = isInferred &&
          isUnflowable(syntacticScope.getVar(varName));

      // 2) We're reading type information from another scope for an
      // inferred variable.
      // var t = null; function f() { (t); }
      boolean nonLocalInferredSlot =
          isInferred &&
          syntacticScope.getParent() != null &&
          var == syntacticScope.getParent().getSlot(varName);

      if (!unflowable && !nonLocalInferredSlot) {
        type = var.getType();
        if (type == null) {
          type = getNativeType(UNKNOWN_TYPE);
        }
      }
    }
  }
  n.setJSType(type);
  return scope;
}
 
Example #6
Source File: Closure_35_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      if (varType.equals(getNativeType(UNKNOWN_TYPE)) &&
          var != syntacticScope.getSlot(qualifiedName)) {
        // If the type of this qualified name has been checked in this scope,
        // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
        return getNativeType(CHECKED_UNKNOWN_TYPE);
      } else {
        return varType;
      }
    }
  }

  JSType propertyType = null;
  if (objType != null) {
    propertyType = objType.findPropertyType(propName);
  }

  if ((propertyType == null || propertyType.isUnknownType()) &&
      qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  return propertyType;
}
 
Example #7
Source File: Closure_35_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseName(Node n, FlowScope scope) {
  String varName = n.getString();
  Node value = n.getFirstChild();
  JSType type = n.getJSType();
  if (value != null) {
    scope = traverse(value, scope);
    updateScopeForTypeChange(scope, n, n.getJSType() /* could be null */,
        getJSType(value));
    return scope;
  } else {
    StaticSlot<JSType> var = scope.getSlot(varName);
    if (var != null) {
      // There are two situations where we don't want to use type information
      // from the scope, even if we have it.

      // 1) The var is escaped in a weird way, e.g.,
      // function f() { var x = 3; function g() { x = null } (x); }
      boolean isInferred = var.isTypeInferred();
      boolean unflowable = isInferred &&
          isUnflowable(syntacticScope.getVar(varName));

      // 2) We're reading type information from another scope for an
      // inferred variable.
      // var t = null; function f() { (t); }
      boolean nonLocalInferredSlot =
          isInferred &&
          syntacticScope.getParent() != null &&
          var == syntacticScope.getParent().getSlot(varName);

      if (!unflowable && !nonLocalInferredSlot) {
        type = var.getType();
        if (type == null) {
          type = getNativeType(UNKNOWN_TYPE);
        }
      }
    }
  }
  n.setJSType(type);
  return scope;
}
 
Example #8
Source File: Closure_25_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      if (varType.equals(getNativeType(UNKNOWN_TYPE)) &&
          var != syntacticScope.getSlot(qualifiedName)) {
        // If the type of this qualified name has been checked in this scope,
        // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
        return getNativeType(CHECKED_UNKNOWN_TYPE);
      } else {
        return varType;
      }
    }
  }

  JSType propertyType = null;
  if (objType != null) {
    propertyType = objType.findPropertyType(propName);
  }

  if ((propertyType == null || propertyType.isUnknownType()) &&
      qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  return propertyType;
}
 
Example #9
Source File: Closure_25_TypeInference_t.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseName(Node n, FlowScope scope) {
  String varName = n.getString();
  Node value = n.getFirstChild();
  JSType type = n.getJSType();
  if (value != null) {
    scope = traverse(value, scope);
    updateScopeForTypeChange(scope, n, n.getJSType() /* could be null */,
        getJSType(value));
    return scope;
  } else {
    StaticSlot<JSType> var = scope.getSlot(varName);
    if (var != null) {
      // There are two situations where we don't want to use type information
      // from the scope, even if we have it.

      // 1) The var is escaped in a weird way, e.g.,
      // function f() { var x = 3; function g() { x = null } (x); }
      boolean isInferred = var.isTypeInferred();
      boolean unflowable = isInferred &&
          isUnflowable(syntacticScope.getVar(varName));

      // 2) We're reading type information from another scope for an
      // inferred variable.
      // var t = null; function f() { (t); }
      boolean nonLocalInferredSlot =
          isInferred &&
          syntacticScope.getParent() != null &&
          var == syntacticScope.getParent().getSlot(varName);

      if (!unflowable && !nonLocalInferredSlot) {
        type = var.getType();
        if (type == null) {
          type = getNativeType(UNKNOWN_TYPE);
        }
      }
    }
  }
  n.setJSType(type);
  return scope;
}
 
Example #10
Source File: Closure_25_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
private JSType getPropertyType(JSType objType, String propName,
    Node n, FlowScope scope) {
  // Scopes sometimes contain inferred type info about qualified names.
  String qualifiedName = n.getQualifiedName();
  StaticSlot<JSType> var = scope.getSlot(qualifiedName);
  if (var != null) {
    JSType varType = var.getType();
    if (varType != null) {
      if (varType.equals(getNativeType(UNKNOWN_TYPE)) &&
          var != syntacticScope.getSlot(qualifiedName)) {
        // If the type of this qualified name has been checked in this scope,
        // then use CHECKED_UNKNOWN_TYPE instead to indicate that.
        return getNativeType(CHECKED_UNKNOWN_TYPE);
      } else {
        return varType;
      }
    }
  }

  JSType propertyType = null;
  if (objType != null) {
    propertyType = objType.findPropertyType(propName);
  }

  if ((propertyType == null || propertyType.isUnknownType()) &&
      qualifiedName != null) {
    // If we find this node in the registry, then we can infer its type.
    ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
    if (regType != null) {
      propertyType = regType.getConstructor();
    }
  }

  return propertyType;
}
 
Example #11
Source File: Closure_25_TypeInference_s.java    From coming with MIT License 5 votes vote down vote up
private FlowScope traverseName(Node n, FlowScope scope) {
  String varName = n.getString();
  Node value = n.getFirstChild();
  JSType type = n.getJSType();
  if (value != null) {
    scope = traverse(value, scope);
    updateScopeForTypeChange(scope, n, n.getJSType() /* could be null */,
        getJSType(value));
    return scope;
  } else {
    StaticSlot<JSType> var = scope.getSlot(varName);
    if (var != null) {
      // There are two situations where we don't want to use type information
      // from the scope, even if we have it.

      // 1) The var is escaped in a weird way, e.g.,
      // function f() { var x = 3; function g() { x = null } (x); }
      boolean isInferred = var.isTypeInferred();
      boolean unflowable = isInferred &&
          isUnflowable(syntacticScope.getVar(varName));

      // 2) We're reading type information from another scope for an
      // inferred variable.
      // var t = null; function f() { (t); }
      boolean nonLocalInferredSlot =
          isInferred &&
          syntacticScope.getParent() != null &&
          var == syntacticScope.getParent().getSlot(varName);

      if (!unflowable && !nonLocalInferredSlot) {
        type = var.getType();
        if (type == null) {
          type = getNativeType(UNKNOWN_TYPE);
        }
      }
    }
  }
  n.setJSType(type);
  return scope;
}
 
Example #12
Source File: ConcreteTypeTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/** {@inheritDoc} */
@Override
public StaticSlot<ConcreteType> getSlot(String name) {
  if (slots.containsKey(name)) {
    return slots.get(name);
  } else if (parent != null) {
    return parent.getSlot(name);
  } else {
    return null;
  }
}
 
Example #13
Source File: Closure_7_ChainableReverseAbstractInterpreter_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Returns the type of a node in the given scope if the node corresponds to a
 * name whose type is capable of being refined.
 * @return The current type of the node if it can be refined, null otherwise.
 */
protected JSType getTypeIfRefinable(Node node, FlowScope scope) {
  switch (node.getType()) {
    case Token.NAME:
      StaticSlot<JSType> nameVar = scope.getSlot(node.getString());
      if (nameVar != null) {
        JSType nameVarType = nameVar.getType();
        if (nameVarType == null) {
          nameVarType = node.getJSType();
        }
        return nameVarType;
      }
      return null;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      if (qualifiedName == null) {
        return null;
      }
      StaticSlot<JSType> propVar = scope.getSlot(qualifiedName);
      JSType propVarType = null;
      if (propVar != null) {
        propVarType = propVar.getType();
      }
      if (propVarType == null) {
        propVarType = node.getJSType();
      }
      if (propVarType == null) {
        propVarType = getNativeType(UNKNOWN_TYPE);
      }
      return propVarType;
  }
  return null;
}
 
Example #14
Source File: Closure_7_ChainableReverseAbstractInterpreter_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Returns the type of a node in the given scope if the node corresponds to a
 * name whose type is capable of being refined.
 * @return The current type of the node if it can be refined, null otherwise.
 */
protected JSType getTypeIfRefinable(Node node, FlowScope scope) {
  switch (node.getType()) {
    case Token.NAME:
      StaticSlot<JSType> nameVar = scope.getSlot(node.getString());
      if (nameVar != null) {
        JSType nameVarType = nameVar.getType();
        if (nameVarType == null) {
          nameVarType = node.getJSType();
        }
        return nameVarType;
      }
      return null;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      if (qualifiedName == null) {
        return null;
      }
      StaticSlot<JSType> propVar = scope.getSlot(qualifiedName);
      JSType propVarType = null;
      if (propVar != null) {
        propVarType = propVar.getType();
      }
      if (propVarType == null) {
        propVarType = node.getJSType();
      }
      if (propVarType == null) {
        propVarType = getNativeType(UNKNOWN_TYPE);
      }
      return propVarType;
  }
  return null;
}
 
Example #15
Source File: TypeInferenceTest.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private JSType getType(String name) {
  assertTrue("The return scope should not be null.", returnScope != null);
  StaticSlot<JSType> var = returnScope.getSlot(name);
  assertTrue("The variable " + name + " is missing from the scope.",
      var != null);
  return var.getType();
}
 
Example #16
Source File: ChainableReverseAbstractInterpreter.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns the type of a node in the given scope if the node corresponds to a
 * name whose type is capable of being refined.
 * @return The current type of the node if it can be refined, null otherwise.
 */
protected JSType getTypeIfRefinable(Node node, FlowScope scope) {
  switch (node.getType()) {
    case Token.NAME:
      StaticSlot<JSType> nameVar = scope.getSlot(node.getString());
      if (nameVar != null) {
        JSType nameVarType = nameVar.getType();
        if (nameVarType == null) {
          nameVarType = node.getJSType();
        }
        return nameVarType;
      }
      return null;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      if (qualifiedName == null) {
        return null;
      }
      StaticSlot<JSType> propVar = scope.getSlot(qualifiedName);
      JSType propVarType = null;
      if (propVar != null) {
        propVarType = propVar.getType();
      }
      if (propVarType == null) {
        propVarType = node.getJSType();
      }
      if (propVarType == null) {
        propVarType = getNativeType(UNKNOWN_TYPE);
      }
      return propVarType;
  }
  return null;
}
 
Example #17
Source File: Closure_6_TypeValidator_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Expect that the property in an interface that this type implements is
 * implemented and correctly typed.
 */
private void expectInterfaceProperty(NodeTraversal t, Node n,
    ObjectType instance, ObjectType implementedInterface, String prop) {
  StaticSlot<JSType> propSlot = instance.getSlot(prop);
  if (propSlot == null) {
    // Not implemented
    String sourceName = n.getSourceFileName();
    sourceName = sourceName == null ? "" : sourceName;
    registerMismatch(instance, implementedInterface,
        report(JSError.make(sourceName, n,
        INTERFACE_METHOD_NOT_IMPLEMENTED,
        prop, implementedInterface.toString(), instance.toString())));
  } else {
    Node propNode = propSlot.getDeclaration() == null ?
        null : propSlot.getDeclaration().getNode();

    // Fall back on the constructor node if we can't find a node for the
    // property.
    propNode = propNode == null ? n : propNode;

    JSType found = propSlot.getType();
    JSType required
        = implementedInterface.getImplicitPrototype().getPropertyType(prop);
    found = found.restrictByNotNullOrUndefined();
    required = required.restrictByNotNullOrUndefined();
    if (!found.canAssignTo(required)) {
      // Implemented, but not correctly typed
      FunctionType constructor =
          implementedInterface.toObjectType().getConstructor();
      registerMismatch(found, required, report(t.makeError(propNode,
          HIDDEN_INTERFACE_PROPERTY_MISMATCH, prop,
          constructor.getTopMostDefiningType(prop).toString(),
          required.toString(), found.toString())));
    }
  }
}
 
Example #18
Source File: Cardumen_0024_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Returns the type of a node in the given scope if the node corresponds to a
 * name whose type is capable of being refined.
 * @return The current type of the node if it can be refined, null otherwise.
 */
protected JSType getTypeIfRefinable(Node node, FlowScope scope) {
  switch (node.getType()) {
    case Token.NAME:
      StaticSlot<JSType> nameVar = scope.getSlot(node.getString());
      if (nameVar != null) {
        JSType nameVarType = nameVar.getType();
        if (nameVarType == null) {
          nameVarType = node.getJSType();
        }
        return nameVarType;
      }
      return null;

    case Token.GETPROP:
      String qualifiedName = node.getQualifiedName();
      if (qualifiedName == null) {
        return null;
      }
      StaticSlot<JSType> propVar = scope.getSlot(qualifiedName);
      JSType propVarType = null;
      if (propVar != null) {
        propVarType = propVar.getType();
      }
      if (propVarType == null) {
        propVarType = node.getJSType();
      }
      if (propVarType == null) {
        propVarType = getNativeType(UNKNOWN_TYPE);
      }
      return propVarType;
  }
  return null;
}
 
Example #19
Source File: SymbolTable.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
private Symbol copySymbolTo(
    StaticSlot<JSType> sym, Node declNode, SymbolScope scope) {
  // All symbols must have declaration nodes.
  Preconditions.checkNotNull(declNode);
  return declareSymbol(
      sym.getName(), sym.getType(), sym.isTypeInferred(), scope, declNode,
      sym.getJSDocInfo());
}
 
Example #20
Source File: TypeValidator.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Expect that the property in an interface that this type implements is
 * implemented and correctly typed.
 */
private void expectInterfaceProperty(NodeTraversal t, Node n,
    ObjectType instance, ObjectType implementedInterface, String prop) {
  StaticSlot<JSType> propSlot = instance.getSlot(prop);
  if (propSlot == null) {
    // Not implemented
    String sourceName = n.getSourceFileName();
    sourceName = sourceName == null ? "" : sourceName;
    registerMismatch(instance, implementedInterface,
        report(JSError.make(sourceName, n,
        INTERFACE_METHOD_NOT_IMPLEMENTED,
        prop, implementedInterface.toString(), instance.toString())));
  } else {
    Node propNode = propSlot.getDeclaration() == null ?
        null : propSlot.getDeclaration().getNode();

    // Fall back on the constructor node if we can't find a node for the
    // property.
    propNode = propNode == null ? n : propNode;

    JSType found = propSlot.getType();
    JSType required
        = implementedInterface.getImplicitPrototype().getPropertyType(prop);
    found = found.restrictByNotNullOrUndefined();
    required = required.restrictByNotNullOrUndefined();
    if (!found.isSubtype(required)) {
      // Implemented, but not correctly typed
      FunctionType constructor =
          implementedInterface.toObjectType().getConstructor();
      registerMismatch(found, required, report(t.makeError(propNode,
          HIDDEN_INTERFACE_PROPERTY_MISMATCH, prop,
          constructor.getTopMostDefiningType(prop).toString(),
          required.toString(), found.toString())));
    }
  }
}
 
Example #21
Source File: LinkedFlowScope.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Get the slot for the given symbol.
 */
@Override
public StaticSlot<JSType> getSlot(String name) {
  if (cache.dirtySymbols.contains(name)) {
    for (LinkedFlowSlot slot = lastSlot;
         slot != null; slot = slot.parent) {
      if (slot.getName().equals(name)) {
        return slot;
      }
    }
  }
  return cache.getSlot(name);
}
 
Example #22
Source File: SymbolTable.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Make sure all the symbols and references in {@code otherSymbolTable}
 * are in this symbol table.
 *
 * Uniqueness of symbols and references is determined by the associated
 * node.
 *
 * If multiple symbol tables are mixed in, we do not check for consistency
 * between symbol tables. The first symbol we see dictates the type
 * information for that symbol.
 */
<S extends StaticSlot<JSType>, R extends StaticReference<JSType>>
void addSymbolsFrom(StaticSymbolTable<S, R> otherSymbolTable) {
  for (S otherSymbol : otherSymbolTable.getAllSymbols()) {
    String name = otherSymbol.getName();
    SymbolScope myScope = createScopeFrom(
        otherSymbolTable.getScope(otherSymbol));

    StaticReference<JSType> decl =
        findBestDeclToAdd(otherSymbolTable, otherSymbol);
    Symbol mySymbol = null;
    if (decl != null) {
      Node declNode = decl.getNode();

      // If we have a declaration node, we can ensure the symbol is declared.
      mySymbol = isAnySymbolDeclared(name, declNode, myScope);
      if (mySymbol == null) {
        mySymbol = copySymbolTo(otherSymbol, declNode, myScope);
      }
    } else {
      // If we don't have a declaration node, we won't be able to declare
      // a symbol in this symbol table. But we may be able to salvage the
      // references if we already have a symbol.
      mySymbol = myScope.getOwnSlot(name);
    }

    if (mySymbol != null) {
      for (R otherRef : otherSymbolTable.getReferences(otherSymbol)) {
        if (isGoodRefToAdd(otherRef)) {
          mySymbol.defineReferenceAt(otherRef.getNode());
        }
      }
    }
  }
}
 
Example #23
Source File: LinkedFlowScope.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Determines whether two slots are meaningfully different for the
 * purposes of data flow analysis.
 */
private boolean diffSlots(StaticSlot<JSType> slotA,
                          StaticSlot<JSType> slotB) {
  boolean aIsNull = slotA == null || slotA.getType() == null;
  boolean bIsNull = slotB == null || slotB.getType() == null;
  if (aIsNull && bIsNull) {
    return false;
  } else if (aIsNull ^ bIsNull) {
    return true;
  }

  // Both slots and types must be non-null.
  return slotA.getType().differsFrom(slotB.getType());
}
 
Example #24
Source File: TightenTypes.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns all assignments that could occur as a result of this property
 * assign action. Each type in the receiver is checked for a property
 * {@code propName}, and if that property exists, it is assigned the type
 * of {@code expression}.
 */
@Override
public Collection<Assignment> getAssignments(ConcreteScope scope) {
  ConcreteType recvType = inferConcreteType(scope, receiver);
  ConcreteType exprType = inferConcreteType(scope, expression);

  List<Assignment> assigns = Lists.newArrayList();
  for (StaticSlot<ConcreteType> prop
       : recvType.getPropertySlots(propName)) {
    assigns.add(new Assignment((ConcreteSlot) prop, exprType));
  }
  return assigns;
}
 
Example #25
Source File: LinkedFlowScope.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Get the slot for the given symbol.
 */
public StaticSlot<JSType> getSlot(String name) {
  if (symbols.containsKey(name)) {
    return symbols.get(name);
  } else {
    return functionScope.getSlot(name);
  }
}
 
Example #26
Source File: ConcreteType.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/** Returns the (non-null) index-th parameters of functions in this set. */
List<StaticSlot<ConcreteType>> getParameterSlots(final int index) {
  return getMatchingTypes(new TypeFilter<StaticSlot<ConcreteType>>(NO_SLOTS) {
    @Override public StaticSlot<ConcreteType> filter(ConcreteType type) {
      return type.isFunction()
          && toFunction().getParameterSlot(index) != null
          ? toFunction().getParameterSlot(index) : null;
    }
  });
}
 
Example #27
Source File: ConcreteType.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns the (non-null) slots for properties with the given name in all
 * instance types in this set.
 */
List<StaticSlot<ConcreteType>> getPropertySlots(final String name) {
  return getMatchingTypes(new TypeFilter<StaticSlot<ConcreteType>>(NO_SLOTS) {
    @Override public StaticSlot<ConcreteType> filter(ConcreteType type) {
      StaticSlot<ConcreteType> slot = null;
      if (type.isInstance()) {
        slot = type.toInstance().getPropertySlot(name);
      }
      return slot;
    }
  });
}
 
Example #28
Source File: ConcreteType.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns the concrete type for the given property from the given type.
 * If the given type is a union type, returns the union of types for the slots
 * of the property.
 */
ConcreteType getPropertyType(final String name) {
  ConcreteType ret = NONE;
  for (StaticSlot<ConcreteType> slot : getPropertySlots(name)) {
    ret = ret.unionWith(slot.getType());
  }
  return ret;
}
 
Example #29
Source File: TightenTypes.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public StaticSlot<ConcreteType> getSlot(String name) {
  StaticSlot<ConcreteType> var = getOwnSlot(name);
  if (var != null) {
    return var;
  } else if (parent != null) {
    return parent.getSlot(name);
  } else {
    return null;
  }
}
 
Example #30
Source File: ConcreteType.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Informally, a function is represented by
 * {@code function (params): returnType} where the {@code params} is a comma
 * separated list of types, the first one being a special
 * {@code this:T} if the function expects a known type for {@code this}.
 */
@Override public String toString() {
  StringBuilder b = new StringBuilder(32);
  b.append("function (");
  boolean hasKnownTypeOfThis = !getThisSlot().getType().isNone();
  if (hasKnownTypeOfThis) {
    b.append("this:");
    b.append(getThisSlot().getType().toString());
  }

  Node n = getFirstParameter();
  if (hasKnownTypeOfThis && n != null) {
    b.append(", ");
  }
  for (int i = 0; n != null; ++i, n = n.getNext()) {
    String paramName = n.getString();
    StaticSlot<ConcreteType> var = getScope().getOwnSlot(paramName);
    b.append(var.getType());
    getParameterSlot(i).getType();
    if (n.getNext() != null) {
      b.append(", ");
    }
  }

  b.append(")");
  if (getReturnSlot().getType() != null) {
    b.append(": ");
    b.append(getReturnSlot().getType().toString());
  }
  return b.toString();
}