/* * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.flex.compiler.internal.codegen.externals.pass; import org.apache.flex.compiler.internal.codegen.externals.reference.ReferenceModel; import com.google.javascript.jscomp.AbstractCompiler; import com.google.javascript.jscomp.NodeTraversal; import com.google.javascript.rhino.JSDocInfo; import com.google.javascript.rhino.Node; public class CollectTypesPass extends AbstractCompilerPass { public CollectTypesPass(ReferenceModel model, AbstractCompiler compiler) { super(model, compiler); } @Override public boolean shouldTraverse(NodeTraversal nodeTraversal, Node n, Node parent) { return n.isBlock() || n.isScript(); } @Override public void visit(NodeTraversal t, Node n, Node parent) { for (Node child : n.children()) { if (child.isVar()) { visitVar(child); } else if (child.isFunction()) { visitFunction(child); } else if (child.isExprResult()) { visitExprResult(child); } } } private void visitExprResult(Node child) { JSDocInfo comment = null; Node container = child.getFirstChild(); if (container.isAssign()) { comment = container.getJSDocInfo(); Node left = container.getFirstChild(); Node right = container.getLastChild(); if (left.isName() && right.isFunction()) { if (comment.isConstructor() || comment.isInterface()) { // Foo = function () {}; model.addClass(container, left.getString()); } } else if (left.isGetProp() && right.isFunction()) { boolean isConstructor = comment != null && (comment.isConstructor() || comment.isInterface()); // foo.bar.Baz = function () {}; if (isConstructor) { model.addClass(container, left.getQualifiedName()); } } } else { comment = container.getJSDocInfo(); boolean isConstructor = comment != null && (comment.getTypedefType() != null); if (isConstructor) { model.addTypeDef(container, container.getQualifiedName()); } } } private void visitFunction(Node child) { JSDocInfo comment = child.getJSDocInfo(); boolean isConstructor = comment != null && (comment.isConstructor() || comment.isInterface()); if (isConstructor) { // function Goo () {}; model.addClass(child, child.getFirstChild().getString()); } else { model.addFunction(child, child.getFirstChild().getString()); } } private void visitVar(Node child) { JSDocInfo comment = child.getJSDocInfo(); Node first = child.getFirstChild(); if (first.isName()) { Node subFirst = first.getFirstChild(); if (subFirst != null && subFirst.isObjectLit()) { if (comment.hasEnumParameterType()) { } else { //System.out.println(first.getFirstChild().toStringTree()); //log("Encountered namespace [" + first.getQualifiedName() + "]"); model.addNamespace(child, first.getQualifiedName()); } } else if (subFirst != null && subFirst.isFunction()) { boolean isConstructor = comment != null && (comment.isConstructor() || comment.isInterface()); // foo.bar.Baz = function () {}; if (isConstructor) { model.addClass(child, first.getString()); } } else { boolean isConstructor = comment != null && (comment.getTypedefType() != null); // * @typedef // var foo; if (isConstructor) { // model.addClass(child, first.getString()); model.addTypeDef(child, first.getString()); } else if (comment != null && comment.isConstant()) { //System.out.println(child.toStringTree()); model.addConstant(child, first.getString()); } } } } }