/* * * 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 java.util.List; import org.apache.flex.compiler.internal.codegen.externals.reference.*; import com.google.javascript.jscomp.AbstractCompiler; import com.google.javascript.jscomp.NodeTraversal; import com.google.javascript.rhino.Node; /** * @author: Frederic Thomas Date: 05/07/2015 Time: 18:16 */ public class CollectImportsPass extends AbstractCompilerPass { public CollectImportsPass(final ReferenceModel model, AbstractCompiler compiler) { super(model, compiler); } @Override public void process(Node externs, Node root) { for (ClassReference reference : model.getClasses()) { collectClassImports(reference); } for (FunctionReference reference : model.getFunctions()) { collectFunctionImports(reference); } } private void collectClassImports(ClassReference reference) { final MethodReference constructor = reference.getConstructor(); final List<ClassReference> superClasses = reference.getSuperClasses(); final List<ClassReference> interfaces = reference.getInterfaces(); final List<ClassReference> extendedInterfaces = reference.getExtendedInterfaces(); final List<FieldReference> fields = reference.getAllFields(); final List<MethodReference> methods = reference.getAllMethods(); for (ClassReference superClass : superClasses) { if (model.isExcludedClass(superClass) == null) { addClassImport(reference, superClass); } } for (ClassReference _interface : interfaces) { if (model.isExcludedClass(_interface) == null) { addClassImport(reference, _interface); } } for (ClassReference _interface : extendedInterfaces) { if (model.isExcludedClass(_interface) == null) { addClassImport(reference, _interface); } } for (FieldReference field : fields) { if (field.isExcluded() == null) { addClassImport(reference, getType(field)); } } if (constructor != null) { for (ParameterReference parameterReference : constructor.getParameters()) { addClassImport(reference, getType(parameterReference)); } } for (MethodReference method : methods) { if (method.isExcluded() == null) { addClassImport(reference, getReturnType(method)); for (ParameterReference parameterReference : method.getParameters()) { addClassImport(reference, getType(parameterReference)); } } } } private void addClassImport(final ClassReference thisReference, final ClassReference referenceToImport) { if (canImport(referenceToImport)) { final String thisPackageName = thisReference.getPackageName(); final String importPackageName = referenceToImport.getPackageName(); if (!importPackageName.equals(thisPackageName)) { thisReference.addImport(referenceToImport); } } } private void collectFunctionImports(final FunctionReference function) { if (function.isExcluded() == null) { ClassReference returnType = getReturnType(function); if (canImport(returnType)) { function.addImport(returnType); } for (ParameterReference parameterReference : function.getParameters()) { ClassReference type = getType(parameterReference); if (canImport(type)) { function.addImport(type); } } } } private ClassReference getType(final FieldReference field) { return model.getClassReference(field.toTypeString()); } private ClassReference getReturnType(final MethodReference method) { return model.getClassReference(method.transformReturnString()); } private ClassReference getReturnType(final FunctionReference function) { return model.getClassReference(function.transformReturnString()); } private ClassReference getType(final ParameterReference parameter) { return model.getClassReference(parameter.getQualifiedName()); } private boolean canImport(ClassReference reference) { return reference != null && reference.isQualifiedName() && model.isExcludedClass(reference) == null; } @Override public boolean shouldTraverse(final NodeTraversal nodeTraversal, final Node n, final Node parent) { return false; } @Override public void visit(final NodeTraversal t, final Node n, final Node parent) { } }