Package com.google.javascript.jscomp

Source Code of com.google.javascript.jscomp.FieldCleanupPass

/*
* Copyright 2011 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;

import com.google.common.collect.ImmutableList;
import com.google.javascript.jscomp.NodeTraversal.AbstractShallowCallback;
import com.google.javascript.jscomp.NodeTraversal.Callback;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.jstype.JSType;
import com.google.javascript.rhino.jstype.JSTypeRegistry;
import com.google.javascript.rhino.jstype.ObjectType;

/**
* A CleanupPass implementation that will remove all field declarations on
* JSTypes contributed by the original file.
* <p>
* This pass is expected to clear out declarations contributed to any JSType,
* even if the constructor declaration is not provided in the file being
* updated.
*
* @author tylerg@google.com (Tyler Goodwin)
*/
public class FieldCleanupPass implements HotSwapCompilerPass {

  private final AbstractCompiler compiler;

  public FieldCleanupPass(AbstractCompiler compiler) {
    this.compiler = compiler;
  }

  @Override
  public void hotSwapScript(Node scriptRoot, Node originalRoot) {
    String srcName = originalRoot.getSourceFileName();
    Callback cb =
        new QualifiedNameSearchTraversal(compiler.getTypeRegistry(), srcName);
    new NodeTraversal(compiler, cb).traverse(originalRoot);
  }

  @Override
  public void process(Node externs, Node root) {
    // FieldCleanupPass should not do work during process.
  }

  /**
   * Search for fields to cleanup by looking for nodes in the tree which are
   * root nodes of qualified names and getting the final token of the qualified
   * name as a candidate field.
   * <p>
   * Once a candidate field is found, ask the {@code JSTypeRegistry} for all
   * JSTypes that have a field with the same name, and check if the field on
   * that type is defined in the file the compiler is cleaning up. If so, remove
   * the field, and update the {@code JSTypeRegistry} to no longer associate the
   * type with the field.
   * <p>
   * This algorithm was chosen for simplicity and is less than optimally
   * efficient in two ways:
   * <p>
   * 1) All types with a matching field name are iterated over (when only types
   * that extend or implement the JSType indicated by the containing object in
   * the found Qualified Name need to be checked).
   * <p>
   * 2) All Qualified Names are checked, even those which are not L-Values or
   * single declarations of an Type Expression. In general field should only be
   * declared as part of an assignment ('ns.Type.a = 3;') or stand alone name
   * declaration ('ns.Type.a;').
   */
  static class QualifiedNameSearchTraversal extends AbstractShallowCallback {

    private final JSTypeRegistry typeRegistry;
    private final String srcName;

    public QualifiedNameSearchTraversal(
        JSTypeRegistry typeRegistry, String srcName) {
      this.typeRegistry = typeRegistry;
      this.srcName = srcName;
    }

    @Override
    public void visit(NodeTraversal t, Node n, Node p) {
      // We are a root GetProp
      if (NodeUtil.isGetProp(n) && !NodeUtil.isGetProp(p)) {
        String propName = getFieldName(n);
        Iterable<JSType> types = ImmutableList.copyOf(
            typeRegistry.getTypesWithProperty(propName));
        for (JSType type : types) {
          ObjectType objType = type.toObjectType();
          if (objType != null) {
            Node pNode = objType.getPropertyNode(propName);
            if (pNode != null && srcName.equals(pNode.getSourceFileName())) {
              typeRegistry.unregisterPropertyOnType(propName, type);
              objType.removeProperty(propName);
            }
          }
        }
      }
    }

    private String getFieldName(Node n) {
      return n.getLastChild().getString();
    }
  }
}
TOP

Related Classes of com.google.javascript.jscomp.FieldCleanupPass

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ts)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');