All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.javascript.jscomp.lint.CheckPrimitiveAsObject Maven / Gradle / Ivy

/*
 * Copyright 2016 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.javascript.jscomp.lint;

import com.google.common.collect.ImmutableSet;
import com.google.javascript.jscomp.AbstractCompiler;
import com.google.javascript.jscomp.DiagnosticType;
import com.google.javascript.jscomp.HotSwapCompilerPass;
import com.google.javascript.jscomp.NodeTraversal;
import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.jscomp.NodeUtil;
import com.google.javascript.rhino.JSDocInfo;
import com.google.javascript.rhino.Node;

/**
 * Check for explicit creation of the object equivalents of primitive types
 * (e.g. Boolean instead of boolean) and their use in type declarations.
 *
 * 

Using these is confusing and gives no benefit. * For example, the result of * {@code typeof (new Boolean(true))} is {@code "object"}. * and the result of * {@code (new Boolean(false)) ? "true" : "false"} is {@code "true"}. */ public final class CheckPrimitiveAsObject extends AbstractPostOrderCallback implements HotSwapCompilerPass { public static final DiagnosticType NEW_PRIMITIVE_OBJECT = DiagnosticType.warning("JSC_PRIMITIVE_OBJECT", "Explicit creation of a {0} object."); public static final DiagnosticType PRIMITIVE_OBJECT_DECLARATION = DiagnosticType.warning( "JSC_PRIMITIVE_OBJECT_DECLARATION", "Declaration of {0} object instead of primitive type."); private static final ImmutableSet PRIMITIVE_OBJECT_CONSTRUCTORS = ImmutableSet.of("Boolean", "Number", "String"); private final AbstractCompiler compiler; public CheckPrimitiveAsObject(AbstractCompiler compiler) { this.compiler = compiler; } @Override public void process(Node externs, Node root) { NodeTraversal.traverse(compiler, root, this); } @Override public void hotSwapScript(Node scriptRoot, Node originalRoot) { NodeTraversal.traverse(compiler, scriptRoot, this); } @Override public void visit(NodeTraversal t, Node n, Node parent) { checkForPrimitiveObjectConstructor(t, n); checkForPrimitiveObjectDeclaration(t, n); } private void checkForPrimitiveObjectDeclaration(NodeTraversal t, Node n) { JSDocInfo jsDocInfo = n.getJSDocInfo(); if (jsDocInfo != null) { for (Node typeRoot : jsDocInfo.getTypeNodes()) { checkTypeNodeForPrimitiveObjectDeclaration(t, typeRoot); } } } private void checkTypeNodeForPrimitiveObjectDeclaration(final NodeTraversal t, Node typeRoot) { NodeUtil.visitPreOrder( typeRoot, new NodeUtil.Visitor() { @Override public void visit(Node node) { if (node.isString()) { String typeName = node.getString(); if (PRIMITIVE_OBJECT_CONSTRUCTORS.contains(typeName)) { t.report(node, PRIMITIVE_OBJECT_DECLARATION, typeName); } } } }); } private void checkForPrimitiveObjectConstructor(NodeTraversal t, Node n) { if (n.isNew()) { Node constructorFunction = n.getFirstChild(); if (constructorFunction.isName()) { String constructorName = constructorFunction.getString(); if (PRIMITIVE_OBJECT_CONSTRUCTORS.contains(constructorName)) { t.report(n, NEW_PRIMITIVE_OBJECT, constructorName); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy