Compile a ClassSymbol from source, optionally using the given compilation unit as
the source tree.
@param tree the compilation unit in which the given ClassSymbol resides,
or null if should be parsed from source
@param c    the ClassSymbol to complete
496480
public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
        if (completionFailureName == c.fullname) {
            throw new CompletionFailure(c, "user-selected completion failure by class name");
        }
        JavaFileObject filename = c.classfile;
        JavaFileObject prev = log.useSource(filename);

        if (tree == null) {
            try {
                tree = parse(filename, filename.getCharContent(false));
            } catch (IOException e) {
                log.error("error.reading.file", filename, JavacFileManager.getMessage(e));
                tree = make.TopLevel(List.<JCTree>nil());
            } finally {
                log.useSource(prev);
            }
        }

        if (!taskListener.isEmpty()) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
            taskListener.started(e);
        }

        // Process module declarations.
        // If module resolution fails, ignore trees, and if trying to
        // complete a specific symbol, throw CompletionFailure.
        // Note that if module resolution failed, we may not even
        // have enough modules available to access java.lang, and
        // so risk getting FatalError("no.java.lang") from MemberEnter.
        if (!modules.enter(List.of(tree), c)) {
            throw new CompletionFailure(c, diags.fragment("cant.resolve.modules"));
        }

        enter.complete(List.of(tree), c);

        if (!taskListener.isEmpty()) {
            TaskEvent e = new TaskEvent(TaskEvent.Kind.ENTER, tree);
            taskListener.finished(e);
        }

        if (enter.getEnv(c) == null) {
            boolean isPkgInfo =
                tree.sourcefile.isNameCompatible("package-info",
                                                 JavaFileObject.Kind.SOURCE);
            boolean isModuleInfo =
                tree.sourcefile.isNameCompatible("module-info",
                                                 JavaFileObject.Kind.SOURCE);
            if (isModuleInfo) {
                if (enter.getEnv(tree.modle) == null) {
                    JCDiagnostic diag =
                        diagFactory.fragment("file.does.not.contain.module");
                    throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
                }
            } else if (isPkgInfo) {
                if (enter.getEnv(tree.packge) == null) {
                    JCDiagnostic diag =
                        diagFactory.fragment("file.does.not.contain.package",
                                                 c.location());
                    throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
                }
            } else {
                JCDiagnostic diag =
                        diagFactory.fragment("file.doesnt.contain.class",
                                            c.getQualifiedName());
                throw new ClassFinder.BadClassFile(c, filename, diag, diagFactory);
            }
        }

        implicitSourceFilesRead = true;
    }
1095253
public void addTree(@Nonnull final ExpressionTree tree) {
    assertNotNull("Tree is null", tree);
    if (last.isEmptySlot()) {
      final ExpressionTreeElement thatTreeRoot = tree.getRoot();
      if (!thatTreeRoot.isEmptySlot()) {
        last = thatTreeRoot;
        last.makeMaxPriority();
      }
    } else {
      last = last.addSubTree(tree);
    }
  }
477838
public static JCTree declarationFor(final Symbol sym, final JCTree tree) {
        class DeclScanner extends TreeScanner {
            JCTree result = null;
            public void scan(JCTree tree) {
                if (tree!=null && result==null)
                    tree.accept(this);
            }
            public void visitTopLevel(JCCompilationUnit that) {
                if (that.packge == sym) result = that;
                else super.visitTopLevel(that);
            }
            public void visitClassDef(JCClassDecl that) {
                if (that.sym == sym) result = that;
                else super.visitClassDef(that);
            }
            public void visitMethodDef(JCMethodDecl that) {
                if (that.sym == sym) result = that;
                else super.visitMethodDef(that);
            }
            public void visitVarDef(JCVariableDecl that) {
                if (that.sym == sym) result = that;
                else super.visitVarDef(that);
            }
            public void visitTypeParameter(JCTypeParameter that) {
                if (that.type != null && that.type.tsym == sym) result = that;
                else super.visitTypeParameter(that);
            }
        }
        DeclScanner s = new DeclScanner();
        tree.accept(s);
        return s.result;
    }
293851
public Type mutableEnclosingInstance(Optional<ClassTree> tree, ClassType type) {
    if (tree.isPresent()
        && !CanBeStaticAnalyzer.referencesOuter(
            tree.get(), ASTHelpers.getSymbol(tree.get()), state)) {
      return null;
    }
    Type enclosing = type.getEnclosingType();
    while (!Type.noType.equals(enclosing)) {
      if (getMarkerOrAcceptedAnnotation(enclosing.tsym, state) == null
          && isThreadSafeType(
                  /* allowContainerTypeParameters= */ false,
                  /* containerTypeParameters= */ ImmutableSet.of(),
                  enclosing)
              .isPresent()) {
        return enclosing;
      }
      enclosing = enclosing.getEnclosingType();
    }
    return null;
  }
231207
public static void generate(ConfigurationImpl configuration,
                                ClassTree classtree)  {
        ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
        for (ClassDoc aClass : configuration.root.classes()) {
            // If -nodeprecated option is set and the containing package is marked
            // as deprecated, do not generate the class-use page. We will still generate
            // the class-use page if the class is marked as deprecated but the containing
            // package is not since it could still be linked from that package-use page.
            if (!(configuration.nodeprecated &&
                  configuration.utils.isDeprecated(aClass.containingPackage())))
                ClassUseWriter.generate(configuration, mapper, aClass);
        }
        for (PackageDoc pkg : configuration.packages) {
            // If -nodeprecated option is set and the package is marked
            // as deprecated, do not generate the package-use page.
            if (!(configuration.nodeprecated && configuration.utils.isDeprecated(pkg)))
                PackageUseWriter.generate(configuration, mapper, pkg);
        }
    }
727372
private void readClassFile(ClassSymbol c) throws IOException {
        int magic = nextInt();
        if (magic != JAVA_MAGIC)
            throw badClassFile("illegal.start.of.class.file");

        minorVersion = nextChar();
        majorVersion = nextChar();
        int maxMajor = Target.MAX().majorVersion;
        int maxMinor = Target.MAX().minorVersion;
        if (majorVersion > maxMajor ||
            majorVersion * 1000 + minorVersion <
            Target.MIN().majorVersion * 1000 + Target.MIN().minorVersion)
        {
            if (majorVersion == (maxMajor + 1))
                log.warning("big.major.version",
                            currentClassFile,
                            majorVersion,
                            maxMajor);
            else
                throw badClassFile("wrong.version",
                                   Integer.toString(majorVersion),
                                   Integer.toString(minorVersion),
                                   Integer.toString(maxMajor),
                                   Integer.toString(maxMinor));
        }
        else if (checkClassFile &&
                 majorVersion == maxMajor &&
                 minorVersion > maxMinor)
        {
            printCCF("found.later.version",
                     Integer.toString(minorVersion));
        }
        indexPool();
        if (signatureBuffer.length < bp) {
            int ns = Integer.highestOneBit(bp) << 1;
            signatureBuffer = new byte[ns];
        }
        readClass(c);
    }
429506
@Nullable
  public static Type getType(@Nullable Tree tree) {
    return tree instanceof JCTree ? ((JCTree) tree).type : null;
  }
822585
private void visitClass(final NodeTraversal t, final Node classNode, final Node parent) {
    checkClassReassignment(classNode);
    // Collect Metadata
    ClassDeclarationMetadata metadata =
        ClassDeclarationMetadata.create(classNode, parent, astFactory);

    if (metadata == null) {
      throw new IllegalStateException(
          "Can only convert classes that are declarations or the right hand"
          + " side of a simple assignment: " + classNode);
    }
    if (metadata.hasSuperClass() && !metadata.getSuperClassNameNode().isQualifiedName()) {
      compiler.report(JSError.make(metadata.getSuperClassNameNode(), DYNAMIC_EXTENDS_TYPE));
      return;
    }

    Preconditions.checkState(
        NodeUtil.isStatement(metadata.getInsertionPoint().getNode()),
        "insertion point must be a statement: %s",
        metadata.getInsertionPoint().getNode());

    Node constructor = null;
    JSDocInfo ctorJSDocInfo = null;
    // Process all members of the class
    Node classMembers = classNode.getLastChild();
    for (Node member : classMembers.children()) {
      if ((member.isComputedProp()
              && (member.getBooleanProp(Node.COMPUTED_PROP_GETTER)
                  || member.getBooleanProp(Node.COMPUTED_PROP_SETTER)))
          || (member.isGetterDef() || member.isSetterDef())) {
        visitNonMethodMember(member, metadata);
      } else if (NodeUtil.isEs6ConstructorMemberFunctionDef(member)) {
        ctorJSDocInfo = member.getJSDocInfo();
        constructor = member.getFirstChild().detach().setJSType(classNode.getJSType());
        constructor.setJSTypeBeforeCast(classNode.getJSTypeBeforeCast());
        if (!metadata.isAnonymous()) {
          // Turns class Foo { constructor: function() {} } into function Foo() {},
          // i.e. attaches the name to the ctor function.
          constructor.replaceChild(
              constructor.getFirstChild(), metadata.getClassNameNode().cloneNode());
        }
      } else if (member.isEmpty()) {
        // Do nothing.
      } else {
        Preconditions.checkState(member.isMemberFunctionDef() || member.isComputedProp(),
            "Unexpected class member:", member);
        Preconditions.checkState(!member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE),
            "Member variables should have been transpiled earlier:", member);
        visitMethod(member, metadata);
      }
    }
    checkNotNull(
        constructor,
        "Es6RewriteClasses expects all classes to have (possibly synthetic) constructors");

    if (metadata.getDefinePropertiesObjForPrototype().hasChildren()) {
      compiler.ensureLibraryInjected("util/global", false);
      Node definePropsCall =
          IR.exprResult(
              astFactory.createCall(
                  createObjectDotDefineProperties(t.getScope()),
                  metadata.getClassPrototypeNode().cloneTree(),
                  metadata.getDefinePropertiesObjForPrototype()));
      definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
      metadata.insertNodeAndAdvance(definePropsCall);
    }

    if (metadata.getDefinePropertiesObjForClass().hasChildren()) {
      compiler.ensureLibraryInjected("util/global", false);
      Node definePropsCall =
          IR.exprResult(
              astFactory.createCall(
                  createObjectDotDefineProperties(t.getScope()),
                  metadata.getFullClassNameNode().cloneTree(),
                  metadata.getDefinePropertiesObjForClass()));
      definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
      metadata.insertNodeAndAdvance(definePropsCall);
    }
    JSDocInfo classJSDoc = NodeUtil.getBestJSDocInfo(classNode);
    JSDocInfoBuilder newInfo = JSDocInfoBuilder.maybeCopyFrom(classJSDoc);

    newInfo.recordConstructor();

    Node enclosingStatement = NodeUtil.getEnclosingStatement(classNode);
    if (metadata.hasSuperClass()) {
      String superClassString = metadata.getSuperClassNameNode().getQualifiedName();
      if (newInfo.isInterfaceRecorded()) {
        newInfo.recordExtendedInterface(
            new JSTypeExpression(
                new Node(Token.BANG, IR.string(superClassString)),
                metadata.getSuperClassNameNode().getSourceFileName()));
      } else {
        newInfo.recordBaseType(
            new JSTypeExpression(
                new Node(Token.BANG, IR.string(superClassString)),
                metadata.getSuperClassNameNode().getSourceFileName()));
      }
      if (!classNode.isFromExterns()) {
        compiler.ensureLibraryInjected("es6/util/inherits", false);
        Node inheritsCall =
            IR.exprResult(
                    astFactory.createCall(
                        astFactory.createQName(t.getScope(), "$jscomp.inherits"),
                        metadata.getFullClassNameNode().cloneTree(),
                        metadata.getSuperClassNameNode().cloneTree()))
                .useSourceInfoIfMissingFromForTree(metadata.getSuperClassNameNode());
        enclosingStatement.getParent().addChildAfter(inheritsCall, enclosingStatement);
      }
    }

    addTypeDeclarations(t.getScope(), metadata, enclosingStatement);

    updateClassJsDoc(ctorJSDocInfo, newInfo);

    if (NodeUtil.isStatement(classNode)) {
      constructor.getFirstChild().setString("");
      Node ctorVar = IR.let(metadata.getClassNameNode().cloneNode(), constructor);
      ctorVar.useSourceInfoIfMissingFromForTree(classNode);
      parent.replaceChild(classNode, ctorVar);
      NodeUtil.addFeatureToScript(t.getCurrentScript(), Feature.LET_DECLARATIONS);
    } else {
      parent.replaceChild(classNode, constructor);
    }
    NodeUtil.markFunctionsDeleted(classNode, compiler);

    if (NodeUtil.isStatement(constructor)) {
      constructor.setJSDocInfo(newInfo.build());
    } else if (parent.isName()) {
      // The constructor function is the RHS of a var statement.
      // Add the JSDoc to the VAR node.
      Node var = parent.getParent();
      var.setJSDocInfo(newInfo.build());
    } else if (constructor.getParent().isName()) {
      // Is a newly created VAR node.
      Node var = constructor.getGrandparent();
      var.setJSDocInfo(newInfo.build());
    } else if (parent.isAssign()) {
      // The constructor function is the RHS of an assignment.
      // Add the JSDoc to the ASSIGN node.
      parent.setJSDocInfo(newInfo.build());
    } else {
      throw new IllegalStateException("Unexpected parent node " + parent);
    }

    FunctionType classType = JSType.toMaybeFunctionType(classNode.getJSType());
    if (classType != null) {
      // classNode is no longer in the AST, so we need to update the reference to it that is
      // stored in the class's type, if any.
      classType.setSource(constructor);
    }

    constructor.putBooleanProp(Node.IS_ES6_CLASS, true);
    t.reportCodeChange();
  }
78151
public void visitApply(JCMethodInvocation tree) {
            if (TreeInfo.name(tree.meth) == names._super) {
                Symbol constructor = TreeInfo.symbol(tree.meth);
                ClassSymbol c = (ClassSymbol)constructor.owner;
                if (c.hasOuterInstance() &&
                    !tree.meth.hasTag(SELECT) &&
                    outerThisStack.head != null)
                    visitSymbol(outerThisStack.head);
            }
            super.visitApply(tree);
        }
242818
public static Klass<Class> java(Class c) {
        return c == null ? null : new Klass<Class>(c, KlassNavigator.JAVA);
    }
1004672
@Nullable
  public static Object constValue(Tree tree) {
    if (tree == null) {
      return null;
    }
    tree = stripParentheses(tree);
    Type type = ASTHelpers.getType(tree);
    Object value;
    if (tree instanceof JCLiteral) {
      value = ((JCLiteral) tree).value;
    } else if (type != null) {
      value = type.constValue();
    } else {
      return null;
    }
    if (type.hasTag(TypeTag.BOOLEAN) && value instanceof Integer) {
      return ((Integer) value) == 1;
    }
    return value;
  }
580191
@SuppressWarnings("unchecked")
    public <T extends JCTree> T translate(T tree) {
        if (tree == null) {
            return null;
        } else {
            tree.accept(this);
            JCTree tmpResult = this.result;
            this.result = null;
            return (T)tmpResult; // XXX cast
        }
    }
743412
public SuppressionInfo forCompilationUnit(CompilationUnitTree tree, VisitorState state) {
    AtomicBoolean generated = new AtomicBoolean(false);
    new SimpleTreeVisitor<Void, Void>() {
      @Override
      public Void visitClass(ClassTree node, Void unused) {
        ClassSymbol symbol = ASTHelpers.getSymbol(node);
        generated.compareAndSet(false, symbol != null && isGenerated(symbol, state));
        return null;
      }
    }.visit(tree.getTypeDecls(), null);
    return new SuppressionInfo(suppressWarningsStrings, customSuppressions, generated.get());
  }
1320251
public void visitTopLevel(JCCompilationUnit tree) {
        tree.defs = translate(tree.defs);
        result = tree;
    }
895315
@Override
  public Void visitCompilationUnit(CompilationUnitTree unit, Void unused) {
    scan(unit.getImports(), null);
    scan(unit.getPackageAnnotations(), null);
    scan(unit.getTypeDecls(), null);
    return null;
  }
1256643
private void generateClassFiles(ClassTree classtree) {
        String[] packageNames = configuration.classDocCatalog.packageNames();
        for (int packageNameIndex = 0; packageNameIndex < packageNames.length;
                packageNameIndex++) {
            generateClassFiles(configuration.classDocCatalog.allClasses(
                packageNames[packageNameIndex]), classtree);
        }
    }
245031
public Iterable<? extends TypeElement> enter(Iterable<? extends CompilationUnitTree> trees)
        throws IOException
    {
        if (trees == null && notYetEntered != null && notYetEntered.isEmpty())
            return List.nil();

        prepareCompiler();

        ListBuffer<JCCompilationUnit> roots = null;

        if (trees == null) {
            // If there are still files which were specified to be compiled
            // (i.e. in fileObjects) but which have not yet been entered,
            // then we make sure they have been parsed and add them to the
            // list to be entered.
            if (notYetEntered.size() > 0) {
                if (!parsed)
                    parse(); // TODO would be nice to specify files needed to be parsed
                for (JavaFileObject file: fileObjects) {
                    JCCompilationUnit unit = notYetEntered.remove(file);
                    if (unit != null) {
                        if (roots == null)
                            roots = new ListBuffer<JCCompilationUnit>();
                        roots.append(unit);
                    }
                }
                notYetEntered.clear();
            }
        }
        else {
            for (CompilationUnitTree cu : trees) {
                if (cu instanceof JCCompilationUnit) {
                    if (roots == null)
                        roots = new ListBuffer<JCCompilationUnit>();
                    roots.append((JCCompilationUnit)cu);
                    notYetEntered.remove(cu.getSourceFile());
                }
                else
                    throw new IllegalArgumentException(cu.toString());
            }
        }

        if (roots == null)
            return List.nil();

        try {
            List<JCCompilationUnit> units = compiler.enterTrees(roots.toList());

            if (notYetEntered.isEmpty())
                compiler = compiler.processAnnotations(units);

            ListBuffer<TypeElement> elements = new ListBuffer<TypeElement>();
            for (JCCompilationUnit unit : units) {
                for (JCTree node : unit.defs) {
                    if (node.hasTag(JCTree.Tag.CLASSDEF)) {
                        JCClassDecl cdef = (JCClassDecl) node;
                        if (cdef.sym != null) // maybe null if errors in anno processing
                            elements.append(cdef.sym);
                    }
                }
            }
            return elements.toList();
        }
        finally {
            compiler.log.flush();
        }
    }