/* * * 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 AddMemberPass extends AbstractCompilerPass { public AddMemberPass(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()) { //log(child); if (child.isExprResult()) { Node first = child.getFirstChild(); if (first.isVar()) { // visitVar(t, n); } else if (first.isFunction()) { // visitFunction(t, n); } else if (first.isAssign()) { if (first.getFirstChild().isGetProp() && first.getLastChild().isFunction()) { // instance or static method visitMethod(t, first); } else { // DOMException.INDEX_SIZE_ERR = 1; // The first child of the assign is the GetProp node, // if later you need the value, either change this or check // for a parent assign node when creating the FieldReference // which the value would be n.getLastChild() // XXX visitStaticField(t, n); //System.err.println(n.toStringTree()); } } else if (first.isGetProp()) { JSDocInfo jsDocInfo = first.getJSDocInfo(); if (jsDocInfo != null && jsDocInfo.hasTypedefType()) { // this is a typedef, and not a member. it was // already handled during the collect types pass. continue; } else if(jsDocInfo != null && (jsDocInfo.getParameterCount() > 0 || jsDocInfo.getReturnType() != null)) { // instance or static method that isn't declared as a // function, but has @param or @returns visitMethodFromJSDoc(t, first); } else { visitGetProp(t, first); } } } } } // n == ASSIGN private void visitMethod(NodeTraversal t, Node n) { String qName = n.getFirstChild().getQualifiedName(); if (n.getFirstChild().isGetProp()) { int protoType = qName.indexOf(".prototype."); if (protoType != -1) { String className = qName.substring(0, protoType); String memberName = qName.substring(protoType + 11, qName.length()); //log("Prototype:: className [" + className // + "] memberName [" + memberName + "]"); model.addMethod(n, className, memberName); } else { String className = qName.substring(0, qName.lastIndexOf(".")); String memberName = qName.substring(qName.lastIndexOf(".") + 1, qName.length()); //log("className [" + className + "] memberName [" // + memberName + "]"); model.addStaticMethod(n, className, memberName); } } else if (n.getFirstChild().isName()) { err("visitMethod() non impl"); log(n); } } private void visitMethodFromJSDoc(NodeTraversal t, Node n) { String qName = n.getQualifiedName(); if (n.isGetProp()) { int protoType = qName.indexOf(".prototype."); if (protoType != -1) { String className = qName.substring(0, protoType); String memberName = qName.substring(protoType + 11, qName.length()); model.addMethod(n, className, memberName); } else { String className = qName.substring(0, qName.lastIndexOf(".")); String memberName = qName.substring(qName.lastIndexOf(".") + 1, qName.length()); model.addStaticMethod(n, className, memberName); } } else if (n.isName()) { err("visitMethod() non impl"); log(n); } } private void visitGetProp(NodeTraversal t, Node n) { String qualifiedName = n.getQualifiedName(); log("visitGetProp [" + qualifiedName + "]"); int protoType = qualifiedName.indexOf(".prototype."); if (protoType != -1) { String className = qualifiedName.substring(0, protoType); String memberName = qualifiedName.substring(protoType + 11, qualifiedName.length()); //log("Prototype:: className [" + className // + "] memberName [" + memberName + "]"); model.addField(n, className, memberName); } else { String className = qualifiedName.substring(0, qualifiedName.lastIndexOf(".")); String memberName = qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1, qualifiedName.length()); //log("className [" + className + "] memberName [" // + memberName + "]"); model.addStaticField(n, className, memberName); } } }