/*
*
* 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);
}
}
}