/** Mark constructor parameter as constant, so it can be annotated readonly */ void markAsConst(ClassMemberDeclaration declaration, Node param) { if (declaration.jsDoc != null && declaration.jsDoc.isConstant()) { param.putBooleanProp(Node.IS_CONSTANT_NAME, true); } } }
/** * Records that the {@link JSDocInfo} being built should have its * {@link JSDocInfo#isConstant()} flag set to {@code true}. * * @return {@code true} if the constancy was recorded and {@code false} * if it was already defined */ public boolean recordConstancy() { if (!currentInfo.isConstant()) { currentInfo.setConstant(true); populated = true; return true; } else { return false; } }
/** * Records the type of a define. * * 'Define' values are special constants that may be manipulated by * the compiler. They are designed to mimic the #define command in * the C preprocessor. */ public boolean recordDefineType(JSTypeExpression type) { if (type != null && !currentInfo.isConstant() && !currentInfo.isDefine() && recordType(type)) { currentInfo.setDefine(true); populated = true; return true; } else { return false; } }
/** * Records the type of a define. * * 'Define' values are special constants that may be manipulated by * the compiler. They are designed to mimic the #define command in * the C preprocessor. */ public boolean recordDefineType(JSTypeExpression type) { if (type != null && !currentInfo.isConstant() && !currentInfo.isDefine() && recordType(type)) { currentInfo.setDefine(true); populated = true; return true; } else { return false; } }
/** * Returns if a property is declared constant. */ private boolean isPropertyDeclaredConstant( ObjectType objectType, String prop) { if (enforceCodingConventions && compiler.getCodingConvention().isConstant(prop)) { return true; } for (; objectType != null; objectType = objectType.getImplicitPrototype()) { JSDocInfo docInfo = objectType.getOwnPropertyJSDocInfo(prop); if (docInfo != null && docInfo.isConstant()) { return true; } } return false; }
/** * Returns if a property is declared constant. */ private boolean isPropertyDeclaredConstant( ObjectType objectType, String prop) { if (enforceCodingConventions && compiler.getCodingConvention().isConstant(prop)) { return true; } for (; objectType != null; objectType = objectType.getImplicitPrototype()) { JSDocInfo docInfo = objectType.getOwnPropertyJSDocInfo(prop); if (docInfo != null && docInfo.isConstant()) { return true; } } return false; }
if (info != null && info.isConstant()) { expectedConst = true; } else {
if (info != null && info.isConstant()) { expectedConst = true; } else {
static boolean isConstToBeInferred(Node nameNode) { JSDocInfo jsdoc = NodeUtil.getBestJSDocInfo(nameNode); boolean isConst = nameNode.getParent().isConst() || isExportLhs(nameNode) || (jsdoc != null && jsdoc.isConstant()); return isConst && !JsdocUtil.hasAnnotatedType(jsdoc) && !NodeUtil.isNamespaceDecl(nameNode); }
@Override protected ConformanceResult checkConformance(NodeTraversal t, Node n) { JSDocInfo jsDoc = n.getJSDocInfo(); if (jsDoc != null && jsDoc.isConstant() && jsDoc.getType() == null) { if (n.isAssign()) { n = n.getFirstChild(); } JSType type = n.getJSType(); if (type != null && type.isUnknownType() && !NodeUtil.isNamespaceDecl(n)) { return ConformanceResult.VIOLATION; } } return ConformanceResult.CONFORMANCE; } }
/** * Temporary function to determine if a node is constant * in the old or new world. This does not check its inputs * carefully because it will go away once we switch to the new * world. */ static boolean isConstantDeclaration( CodingConvention convention, JSDocInfo info, Node node) { if (info != null && info.isConstant()) { return true; } if (node.getBooleanProp(Node.IS_CONSTANT_VAR)) { return true; } switch (node.getType()) { case Token.NAME: return NodeUtil.isConstantByConvention(convention, node); case Token.GETPROP: return node.isQualifiedName() && NodeUtil.isConstantByConvention(convention, node.getLastChild()); } return false; }
/** * Returns the super class of the given type that has a constructor. */ private static JSType getFinalParentClass(JSType type) { if (type != null) { ObjectType iproto = ObjectType.cast(type).getImplicitPrototype(); while (iproto != null && iproto.getConstructor() == null) { iproto = iproto.getImplicitPrototype(); } if (iproto != null) { Node source = iproto.getConstructor().getSource(); JSDocInfo jsDoc = source != null ? NodeUtil.getBestJSDocInfo(source) : null; if (jsDoc != null && jsDoc.isConstant()) { return iproto; } } } return null; } }
@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); 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); } } } }
@Override public void visit(NodeTraversal t, Node n, Node parent) { // Note: Constant properties annotations are not propagated. if (n.isName() || n.isStringKey()) { 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); 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); } } } }
@Override public void visit(NodeTraversal t, Node n, Node parent) { JSDocInfo bestJSDocInfo = NodeUtil.getBestJSDocInfo(n); if (bestJSDocInfo == null) { return; } // Add visibility for private and protected. if (Visibility.PRIVATE.equals(bestJSDocInfo.getVisibility())) { n.putProp(Node.ACCESS_MODIFIER, Visibility.PRIVATE); } else if (Visibility.PROTECTED.equals(bestJSDocInfo.getVisibility())) { n.putProp(Node.ACCESS_MODIFIER, Visibility.PROTECTED); } // Change variable declarations to constants if (bestJSDocInfo.isConstant() && (n.isVar() || n.isLet())) { n.setToken(Token.CONST); } } }
/** * @return Whether the given node is a @private property declaration that is not marked constant. */ private boolean isCandidatePropertyDefinition(Node n) { if (!NodeUtil.isLhsOfAssign(n)) { return false; } Node target = n.getFirstChild(); // Check whether the given property access is on 'this' or a static property on a class. if (!(target.isThis() || isConstructor(target))) { return false; } JSDocInfo info = NodeUtil.getBestJSDocInfo(n); return info != null && info.getVisibility() == Visibility.PRIVATE && !info.isConstant() && !info.hasTypedefType() && !info.hasEnumParameterType() && !info.isInterface() && !isFunctionProperty(n); }
private void considerVar(Var v, ReferenceCollection refCollection) { Node nameNode = v.getNameNode(); JSDocInfo docInfo = v.getJSDocInfo(); if (docInfo != null && docInfo.isConstant()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && nameNode.getParent().isConst()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && compiler.getCodingConvention().isConstant(nameNode.getString())) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && refCollection != null && refCollection.isWellDefined() && refCollection.isAssignedOnceInLifetime() && refCollection.firstReferenceIsAssigningDeclaration()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } } }
private void considerVar(Var v, ReferenceCollection refCollection) { Node nameNode = v.getNameNode(); JSDocInfo docInfo = v.getJSDocInfo(); if (docInfo != null && docInfo.isConstant()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && nameNode.getParent().isConst()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && compiler.getCodingConvention().isConstant(nameNode.getString())) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } else if (nameNode != null && refCollection != null && refCollection.isWellDefined() && refCollection.isAssignedOnceInLifetime() && refCollection.firstReferenceIsAssigningDeclaration()) { nameNode.putBooleanProp(Node.IS_CONSTANT_VAR, true); } } }
if (info != null && info.isConstant()) { return true;
else if (comment != null && comment.isConstant())