Java Code Examples for com.google.javascript.rhino.JSDocInfo#isConstant()

The following examples show how to use com.google.javascript.rhino.JSDocInfo#isConstant() . 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: Normalize.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // Note: Constant properties annotations are not propagated.
  if (n.isName()) {
    if (n.getString().isEmpty()) {
      return;
    }

    JSDocInfo info = null;
    // Find the JSDocInfo for a top-level variable.
    Var var = t.getScope().getVar(n.getString());
    if (var != null) {
      info = var.getJSDocInfo();
    }

    boolean shouldBeConstant =
        (info != null && info.isConstant()) ||
        NodeUtil.isConstantByConvention(
            compiler.getCodingConvention(), n, parent);
    boolean isMarkedConstant = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (shouldBeConstant && !isMarkedConstant) {
      if (assertOnChange) {
        String name = n.getString();
        throw new IllegalStateException(
            "Unexpected const change.\n" +
            "  name: "+ name + "\n" +
            "  parent:" + n.getParent().toStringTree());
      }
      n.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }
  }
}
 
Example 2
Source File: Closure_79_Normalize_s.java    From coming with MIT License 5 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // Note: Constant properties annotations are not propagated.
  if (n.getType() == Token.NAME) {
    if (n.getString().isEmpty()) {
      return;
    }

    JSDocInfo info = null;
    // Find the JSDocInfo for a top level variable.
    Var var = t.getScope().getVar(n.getString());
    if (var != null) {
      info = var.getJSDocInfo();
    }

    boolean shouldBeConstant =
        (info != null && info.isConstant()) ||
        NodeUtil.isConstantByConvention(
            compiler.getCodingConvention(), n, parent);
    boolean isMarkedConstant = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (shouldBeConstant && !isMarkedConstant) {
      if (assertOnChange) {
        String name = n.getString();
        throw new IllegalStateException(
            "Unexpected const change.\n" +
            "  name: "+ name + "\n" +
            "  parent:" + n.getParent().toStringTree());
      }
      n.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }
  }
}
 
Example 3
Source File: CheckAccessControls.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns if a property is declared constant.
 */
private static boolean isPropertyDeclaredConstant(
    ObjectType objectType, String prop) {
  for (;
       // Only objects with reference names can have constant properties.
       objectType != null && objectType.hasReferenceName();

       objectType = objectType.getImplicitPrototype()) {
    JSDocInfo docInfo = objectType.getOwnPropertyJSDocInfo(prop);
    if (docInfo != null && docInfo.isConstant()) {
      return true;
    }
  }
  return false;
}
 
Example 4
Source File: Closure_102_Normalize_s.java    From coming with MIT License 5 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  // Note: Constant properties annotations are not propagated.
  if (n.getType() == Token.NAME) {
    if (n.getString().isEmpty()) {
      return;
    }

    JSDocInfo info = null;
    // Find the JSDocInfo for a top level variable.
    Var var = t.getScope().getVar(n.getString());
    if (var != null) {
      info = var.getJSDocInfo();
    }

    if ((info != null && info.isConstant()) &&
        !n.getBooleanProp(Node.IS_CONSTANT_NAME)) {
      n.putBooleanProp(Node.IS_CONSTANT_NAME, true);
      if (assertOnChange) {
        String name = n.getString();
        throw new IllegalStateException(
            "Unexpected const change.\n" +
            "  name: "+ name + "\n" +
            "  gramps:" + n.getParent().getParent().toStringTree());
      }
      // Even though the AST has changed (an annotation was added),
      // the annotations are not compared so don't report the change.
      // reportCodeChange("constant annotation");
    }
  }
}
 
Example 5
Source File: Closure_79_Normalize_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (n.getType() == Token.NAME) {
    String name = n.getString();
    if (n.getString().isEmpty()) {
      return;
    }

    boolean isConst = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (checkUserDeclarations) {
      boolean expectedConst = false;
      CodingConvention convention = compiler.getCodingConvention();
      if (NodeUtil.isConstantName(n)
          || NodeUtil.isConstantByConvention(convention, n, parent)) {
        expectedConst = true;
      } else {
        expectedConst = false;

        JSDocInfo info = null;
        Var var = t.getScope().getVar(n.getString());
        if (var != null) {
          info = var.getJSDocInfo();
        }

        if (info != null && info.isConstant()) {
          expectedConst = true;
        } else {
          expectedConst = false;
        }
      }

      if (expectedConst) {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " is not annotated as constant.");
      } else {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " should not be annotated as constant.");
      }
    }

    Boolean value = constantMap.get(name);
    if (value == null) {
      constantMap.put(name, isConst);
    } else {
      Preconditions.checkState(value.booleanValue() == isConst,
          "The name " + name + " is not consistently annotated as " +
          "constant.");
    }
  }
}
 
Example 6
Source File: MemberCollector.java    From jsinterop-generator with Apache License 2.0 4 votes vote down vote up
private static boolean isConstant(StaticTypedSlot jsField) {
  JSDocInfo jsdoc = jsField.getJSDocInfo();
  return jsdoc != null && jsdoc.isConstant();
}
 
Example 7
Source File: Closure_71_CheckAccessControls_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Determines whether the given property with @const tag got reassigned
 * @param t The current traversal.
 * @param getprop The getprop node.
 */
private void checkConstantProperty(NodeTraversal t,
    Node getprop) {
  // Check whether the property is modified
  Node parent = getprop.getParent();
  if (!(NodeUtil.isAssignmentOp(parent) && parent.getFirstChild() == getprop)
      && (parent.getType() != Token.INC) && (parent.getType() != Token.DEC)) {
    return;
  }

  ObjectType objectType =
    ObjectType.cast(dereference(getprop.getFirstChild().getJSType()));
  String propertyName = getprop.getLastChild().getString();

  // Check whether constant properties are reassigned
  if (objectType != null) {
    ObjectType oType = objectType;
    while (oType != null) {
      if (oType.hasReferenceName()) {
        if (initializedConstantProperties.containsEntry(
                oType.getReferenceName(), propertyName)) {
          compiler.report(
              t.makeError(getprop, CONST_PROPERTY_REASSIGNED_VALUE,
                  propertyName));
          break;
        }
      }
      oType = oType.getImplicitPrototype();
    }

    JSDocInfo info = objectType.getOwnPropertyJSDocInfo(propertyName);
    if (info != null && info.isConstant()
        && objectType.hasReferenceName()) {
      initializedConstantProperties.put(objectType.getReferenceName(),
          propertyName);
    }

    // Add the prototype when we're looking at an instance object
    if (objectType.isInstanceType()) {
      ObjectType prototype = objectType.getImplicitPrototype();
      if (prototype != null) {
        JSDocInfo prototypeInfo
          = prototype.getOwnPropertyJSDocInfo(propertyName);
        if (prototypeInfo != null && prototypeInfo.isConstant()
            && prototype.hasReferenceName()) {
          initializedConstantProperties.put(prototype.getReferenceName(),
              propertyName);
        }
      }
    }
  }
}
 
Example 8
Source File: Closure_130_CollapseProperties_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Updates the first initialization (a.k.a "declaration") of a global name
 * that occurs at an ASSIGN node. See comment for
 * {@link #updateObjLitOrFunctionDeclaration}.
 *
 * @param n An object representing a global name (e.g. "a", "a.b.c")
 * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
 */
private void updateObjLitOrFunctionDeclarationAtAssignNode(
    Name n, String alias, boolean canCollapseChildNames) {
  // NOTE: It's important that we don't add additional nodes
  // (e.g. a var node before the exprstmt) because the exprstmt might be
  // the child of an if statement that's not inside a block).

  Ref ref = n.getDeclaration();
  Node rvalue = ref.node.getNext();
  Node varNode = new Node(Token.VAR);
  Node varParent = ref.node.getAncestor(3);
  Node gramps = ref.node.getAncestor(2);
  boolean isObjLit = rvalue.isObjectLit();
  boolean insertedVarNode = false;

  if (isObjLit && n.canEliminate()) {
    // Eliminate the object literal altogether.
    varParent.replaceChild(gramps, varNode);
    ref.node = null;
    insertedVarNode = true;

  } else if (!n.isSimpleName()) {
    // Create a VAR node to declare the name.
    if (rvalue.isFunction()) {
      checkForHosedThisReferences(rvalue, n.docInfo, n);
    }

    ref.node.getParent().removeChild(rvalue);

    Node nameNode = NodeUtil.newName(
        compiler.getCodingConvention(),
        alias, ref.node.getAncestor(2), n.getFullName());

    JSDocInfo info = ref.node.getParent().getJSDocInfo();
    if (ref.node.getLastChild().getBooleanProp(Node.IS_CONSTANT_NAME) ||
        (info != null && info.isConstant())) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }

    if (info != null) {
      varNode.setJSDocInfo(info);
    }
    varNode.addChildToBack(nameNode);
    nameNode.addChildToFront(rvalue);
    varParent.replaceChild(gramps, varNode);

    // Update the node ancestry stored in the reference.
    ref.node = nameNode;
    insertedVarNode = true;
  }

  if (canCollapseChildNames) {
    if (isObjLit) {
      declareVarsForObjLitValues(
          n, alias, rvalue,
          varNode, varParent.getChildBefore(varNode), varParent);
    }

    addStubsForUndeclaredProperties(n, alias, varParent, varNode);
  }

  if (insertedVarNode) {
    if (!varNode.hasChildren()) {
      varParent.removeChild(varNode);
    }
    compiler.reportCodeChange();
  }
}
 
Example 9
Source File: Closure_54_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.getType() == Token.FUNCTION &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.getType() == Token.OBJECTLIT) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.getType() == Token.OR) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.getType() == Token.NAME
                && lValue.getType() == Token.NAME
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 10
Source File: Closure_70_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.getType() == Token.FUNCTION &&
      shouldUseFunctionLiteralType(
          (FunctionType) rValue.getJSType(), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.getType() == Token.OBJECTLIT) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.getType() == Token.OR) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.getType() == Token.NAME
                && lValue.getType() == Token.NAME
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 11
Source File: Closure_70_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.getType() == Token.FUNCTION &&
      shouldUseFunctionLiteralType(
          (FunctionType) rValue.getJSType(), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.getType() == Token.OBJECTLIT) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.getType() == Token.OR) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.getType() == Token.NAME
                && lValue.getType() == Token.NAME
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 12
Source File: Closure_102_Normalize_s.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (n.getType() == Token.NAME) {
    String name = n.getString();
    if (n.getString().isEmpty()) {
      return;
    }

    boolean isConst = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (checkUserDeclarations) {
      boolean expectedConst = false;
      if (NodeUtil.isConstantName(n)
          || compiler.getCodingConvention().isConstant(n.getString())) {
        expectedConst = true;
      } else {
        expectedConst = false;

        JSDocInfo info = null;
        Var var = t.getScope().getVar(n.getString());
        if (var != null) {
          info = var.getJSDocInfo();
        }

        if (info != null && info.isConstant()) {
          expectedConst = true;
        } else {
          expectedConst = false;
        }
      }

      if (expectedConst) {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " is not annotated as constant.");
      } else {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " should not be annotated as constant.");
      }
    }

    Boolean value = constantMap.get(name);
    if (value == null) {
      constantMap.put(name, isConst);
    } else {
      Preconditions.checkState(value.booleanValue() == isConst,
          "The name " + name + " is not consistently annotated as " +
          "constant.");
    }
  }
}
 
Example 13
Source File: Closure_102_Normalize_t.java    From coming with MIT License 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (n.getType() == Token.NAME) {
    String name = n.getString();
    if (n.getString().isEmpty()) {
      return;
    }

    boolean isConst = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (checkUserDeclarations) {
      boolean expectedConst = false;
      if (NodeUtil.isConstantName(n)
          || compiler.getCodingConvention().isConstant(n.getString())) {
        expectedConst = true;
      } else {
        expectedConst = false;

        JSDocInfo info = null;
        Var var = t.getScope().getVar(n.getString());
        if (var != null) {
          info = var.getJSDocInfo();
        }

        if (info != null && info.isConstant()) {
          expectedConst = true;
        } else {
          expectedConst = false;
        }
      }

      if (expectedConst) {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " is not annotated as constant.");
      } else {
        Preconditions.checkState(expectedConst == isConst,
            "The name " + name + " should not be annotated as constant.");
      }
    }

    Boolean value = constantMap.get(name);
    if (value == null) {
      constantMap.put(name, isConst);
    } else {
      Preconditions.checkState(value.booleanValue() == isConst,
          "The name " + name + " is not consistently annotated as " +
          "constant.");
    }
  }
}
 
Example 14
Source File: Closure_43_TypedScopeCreator_s.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 15
Source File: Closure_17_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          JSDocInfo rValueInfo = rValue.getJSDocInfo();
          if (rValueInfo != null && rValueInfo.hasType()) {
            // If rValue has a type-cast, we use the type in the type-cast.
            return rValueInfo.getType().evaluate(scope, typeRegistry);
          } else if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            // If rValue's type was already computed during scope creation,
            // then we can safely use that.
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 16
Source File: TypedScopeCreator.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Determines whether a qualified name is inferred.
 * NOTE(nicksantos): Determining whether a property is declared or not
 * is really really obnoxious.
 *
 * The problem is that there are two (equally valid) coding styles:
 *
 * (function() {
 *   /* The authoritative definition of goog.bar. /
 *   goog.bar = function() {};
 * })();
 *
 * function f() {
 *   goog.bar();
 *   /* Reset goog.bar to a no-op. /
 *   goog.bar = function() {};
 * }
 *
 * In a dynamic language with first-class functions, it's very difficult
 * to know which one the user intended without looking at lots of
 * contextual information (the second example demonstrates a small case
 * of this, but there are some really pathological cases as well).
 *
 * The current algorithm checks if either the declaration has
 * JsDoc type information, or @const with a known type,
 * or a function literal with a name we haven't seen before.
 */
private boolean isQualifiedNameInferred(
    String qName, Node n, JSDocInfo info,
    Node rhsValue, JSType valueType) {
  if (valueType == null) {
    return true;
  }

  boolean inferred = true;
  if (info != null) {
    inferred = !(info.hasType()
        || info.hasEnumParameterType()
        || (info.isConstant() && valueType != null
            && !valueType.isUnknownType())
        || FunctionTypeBuilder.isFunctionTypeDeclaration(info));
  }

  if (inferred && rhsValue != null && rhsValue.isFunction()) {
    if (info != null) {
      return false;
    } else if (!scope.isDeclared(qName, false) &&
        n.isUnscopedQualifiedName()) {

      // Check if this is in a conditional block.
      // Functions assigned in conditional blocks are inferred.
      for (Node current = n.getParent();
           !(current.isScript() || current.isFunction());
           current = current.getParent()) {
        if (NodeUtil.isControlStructure(current)) {
          return true;
        }
      }

      // Check if this is assigned in an inner scope.
      // Functions assigned in inner scopes are inferred.
      AstFunctionContents contents =
          getFunctionAnalysisResults(scope.getRootNode());
      if (contents == null ||
          !contents.getEscapedQualifiedNames().contains(qName)) {
        return false;
      }
    }
  }
  return inferred;
}
 
Example 17
Source File: Normalize.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
  if (n.isName()) {
    String name = n.getString();
    if (n.getString().isEmpty()) {
      return;
    }

    boolean isConst = n.getBooleanProp(Node.IS_CONSTANT_NAME);
    if (checkUserDeclarations) {
      boolean expectedConst = false;
      CodingConvention convention = compiler.getCodingConvention();
      if (NodeUtil.isConstantName(n)
          || NodeUtil.isConstantByConvention(convention, n, parent)) {
        expectedConst = true;
      } else {
        expectedConst = false;

        JSDocInfo info = null;
        Var var = t.getScope().getVar(n.getString());
        if (var != null) {
          info = var.getJSDocInfo();
        }

        if (info != null && info.isConstant()) {
          expectedConst = true;
        } else {
          expectedConst = false;
        }
      }

      if (expectedConst) {
        Preconditions.checkState(expectedConst == isConst,
            "The name %s is not annotated as constant.", name);
      } else {
        Preconditions.checkState(expectedConst == isConst,
            "The name %s should not be annotated as constant.", name);
      }
    }

    Boolean value = constantMap.get(name);
    if (value == null) {
      constantMap.put(name, isConst);
    } else {
      Preconditions.checkState(value.booleanValue() == isConst,
          "The name %s is not consistently annotated as constant.", name);
    }
  }
}
 
Example 18
Source File: CollapseProperties.java    From astor with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Updates the first initialization (a.k.a "declaration") of a global name
 * that occurs at an ASSIGN node. See comment for
 * {@link #updateObjLitOrFunctionDeclaration}.
 *
 * @param n An object representing a global name (e.g. "a", "a.b.c")
 * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
 */
private void updateObjLitOrFunctionDeclarationAtAssignNode(
    Name n, String alias, boolean canCollapseChildNames) {
  // NOTE: It's important that we don't add additional nodes
  // (e.g. a var node before the exprstmt) because the exprstmt might be
  // the child of an if statement that's not inside a block).

  Ref ref = n.getDeclaration();
  Node rvalue = ref.node.getNext();
  Node varNode = new Node(Token.VAR);
  Node varParent = ref.node.getAncestor(3);
  Node gramps = ref.node.getAncestor(2);
  boolean isObjLit = rvalue.isObjectLit();
  boolean insertedVarNode = false;

  if (isObjLit && n.canEliminate()) {
    // Eliminate the object literal altogether.
    varParent.replaceChild(gramps, varNode);
    ref.node = null;
    insertedVarNode = true;

  } else if (!n.isSimpleName()) {
    // Create a VAR node to declare the name.
    if (rvalue.isFunction()) {
      checkForHosedThisReferences(rvalue, n.docInfo, n);
    }

    ref.node.getParent().removeChild(rvalue);

    Node nameNode = NodeUtil.newName(
        compiler.getCodingConvention(),
        alias, ref.node.getAncestor(2), n.getFullName());

    JSDocInfo info = ref.node.getParent().getJSDocInfo();
    if (ref.node.getLastChild().getBooleanProp(Node.IS_CONSTANT_NAME) ||
        (info != null && info.isConstant())) {
      nameNode.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    }

    if (info != null) {
      varNode.setJSDocInfo(info);
    }
    varNode.addChildToBack(nameNode);
    nameNode.addChildToFront(rvalue);
    varParent.replaceChild(gramps, varNode);

    // Update the node ancestry stored in the reference.
    ref.node = nameNode;
    insertedVarNode = true;
  }

  if (canCollapseChildNames) {
    if (isObjLit) {
      declareVarsForObjLitValues(
          n, alias, rvalue,
          varNode, varParent.getChildBefore(varNode), varParent);
    }

    addStubsForUndeclaredProperties(n, alias, varParent, varNode);
  }

  if (insertedVarNode) {
    if (!varNode.hasChildren()) {
      varParent.removeChild(varNode);
    }
    compiler.reportCodeChange();
  }
}
 
Example 19
Source File: Closure_43_TypedScopeCreator_t.java    From coming with MIT License 4 votes vote down vote up
/**
 * Look for a type declaration on a property assignment
 * (in an ASSIGN or an object literal key).
 *
 * @param info The doc info for this property.
 * @param lValue The l-value node.
 * @param rValue The node that {@code n} is being initialized to,
 *     or {@code null} if this is a stub declaration.
 */
private JSType getDeclaredType(String sourceName, JSDocInfo info,
    Node lValue, @Nullable Node rValue) {
  if (info != null && info.hasType()) {
    return getDeclaredTypeInAnnotation(sourceName, lValue, info);
  } else if (rValue != null && rValue.isFunction() &&
      shouldUseFunctionLiteralType(
          JSType.toMaybeFunctionType(rValue.getJSType()), info, lValue)) {
    return rValue.getJSType();
  } else if (info != null) {
    if (info.hasEnumParameterType()) {
      if (rValue != null && rValue.isObjectLit()) {
        return rValue.getJSType();
      } else {
        return createEnumTypeFromNodes(
            rValue, lValue.getQualifiedName(), info, lValue);
      }
    } else if (info.isConstructor() || info.isInterface()) {
      return createFunctionTypeFromNodes(
          rValue, lValue.getQualifiedName(), info, lValue);
    } else {
      // Check if this is constant, and if it has a known type.
      if (info.isConstant()) {
        JSType knownType = null;
        if (rValue != null) {
          if (rValue.getJSType() != null
              && !rValue.getJSType().isUnknownType()) {
            return rValue.getJSType();
          } else if (rValue.isOr()) {
            // Check for a very specific JS idiom:
            // var x = x || TYPE;
            // This is used by Closure's base namespace for esoteric
            // reasons.
            Node firstClause = rValue.getFirstChild();
            Node secondClause = firstClause.getNext();
            boolean namesMatch = firstClause.isName()
                && lValue.isName()
                && firstClause.getString().equals(lValue.getString());
            if (namesMatch && secondClause.getJSType() != null
                && !secondClause.getJSType().isUnknownType()) {
              return secondClause.getJSType();
            }
          }
        }
      }
    }
  }

  return getDeclaredTypeInAnnotation(sourceName, lValue, info);
}
 
Example 20
Source File: Closure_43_TypedScopeCreator_t.java    From coming with MIT License 3 votes vote down vote up
/**
 * Determines whether a qualified name is inferred.
 * NOTE(nicksantos): Determining whether a property is declared or not
 * is really really obnoxious.
 *
 * The problem is that there are two (equally valid) coding styles:
 *
 * (function() {
 *   /* The authoritative definition of goog.bar. /
 *   goog.bar = function() {};
 * })();
 *
 * function f() {
 *   goog.bar();
 *   /* Reset goog.bar to a no-op. /
 *   goog.bar = function() {};
 * }
 *
 * In a dynamic language with first-class functions, it's very difficult
 * to know which one the user intended without looking at lots of
 * contextual information (the second example demonstrates a small case
 * of this, but there are some really pathological cases as well).
 *
 * The current algorithm checks if either the declaration has
 * jsdoc type information, or @const with a known type,
 * or a function literal with a name we haven't seen before.
 */
private boolean isQualifiedNameInferred(
    String qName, Node n, JSDocInfo info,
    Node rhsValue, JSType valueType) {
  if (valueType == null) {
    return true;
  }

  boolean inferred = true;
  if (info != null) {
    inferred = !(info.hasType()
        || info.hasEnumParameterType()
        || (info.isConstant() && valueType != null
            && !valueType.isUnknownType())
        || FunctionTypeBuilder.isFunctionTypeDeclaration(info));
  }

  if (inferred && rhsValue != null && rhsValue.isFunction()) {
    if (info != null) {
      inferred = false;
    } else if (!scope.isDeclared(qName, false) &&
               n.isUnscopedQualifiedName()) {
      inferred = false;
    }
  }
  return inferred;
}