blob: ce10d46a8b5a91831f3c492cbef4212881bb0bf0 [file] [log] [blame]
/*
*
* 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.as.codegen;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.flex.abc.semantics.Name;
import org.apache.flex.abc.semantics.Namespace;
import org.apache.flex.abc.semantics.Nsset;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.IFunctionDefinition;
import org.apache.flex.compiler.definitions.IMemberedDefinition;
import org.apache.flex.compiler.definitions.INamespaceDefinition;
import org.apache.flex.compiler.definitions.metadata.IMetaTag;
import org.apache.flex.compiler.internal.driver.IBackend;
import org.apache.flex.compiler.internal.legacy.MemberedDefinitionUtils;
import org.apache.flex.compiler.internal.legacy.ASDefinitionFilter;
import org.apache.flex.compiler.internal.legacy.ASDefinitionFilter.AccessValue;
import org.apache.flex.compiler.internal.legacy.ASDefinitionFilter.ClassificationValue;
import org.apache.flex.compiler.internal.legacy.ASDefinitionFilter.SearchScopeValue;
import org.apache.flex.compiler.internal.workspaces.Workspace;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.units.ICompilationUnit;
import org.apache.flex.swf.SWFFrame;
import static org.apache.flex.abc.ABCConstants.OP_nop;
/**
* JSSharedData contains information that is being shared across
* JSCompilationUnit, JSGenerator, and JSEmitter instances.
* JSSharedData.COMPILER_VERSION holds FalconJS's version, which uses the Falcon
* change list number as the major revision number. The minor revision number
* represents FalconJS's internal version within the Falcon change list number
* it is based on. This implementation is part of FalconJS. For more details on
* FalconJS see org.apache.flex.compiler.JSDriver
*/
public class JSSharedData
{
public static String COMPILER_NAME = "MXMLJSC";
public final static String COMPILER_VERSION = "329449.1";
public final static JSSharedData instance = new JSSharedData();
public static IBackend backend = null;
public static Workspace workspace = null;
public final static String JS_FRAMEWORK_NAME = "org.apache.flex.FlexGlobal";
public final static String ROOT_NAME = ""; // JS_FRAMEWORK_NAME + ".root.";
public static String FRAMEWORK_CLASS = "browser.JQueryFramework";
public static String BUILT_IN = "builtin.abc";
public static String MAIN = null;
public static Boolean NO_EXPORTS = true;
public static Boolean OUTPUT_TIMESTAMPS = false;
public static Boolean OUTPUT_ISOLATED = true;
public static Boolean GENERATE_TEST_CASE = false;
public static Boolean WARN_PERFORMANCE_LOSS = false;
public static Boolean WARN_RUNTIME_NAME_LOOKUP = false; // JSWarnRuntimeNameLookupProblem
public static Boolean WARN_CLASS_INIT = false; // JSWarnClassInitProblem
public static Boolean DEBUG = false;
public static Boolean OPTIMIZE = false;
public static Boolean EXTEND_DOM = true;
public static Boolean KEEP_GENERATED_AS = false;
public static PrintStream STDOUT = System.out;
public static PrintStream STDERR = System.err;
public static String OUTPUT_FOLDER = ".";
public static String OUTPUT_EXTENSION = "js";
public static String SDK_PATH = null;
public static String CLOSURE_compilation_level = "SIMPLE_OPTIMIZATIONS";
public static List<String> CLOSURE_externs = null;
public static List<String> CLOSURE_js = null;
public static String CLOSURE_create_source_map = null;
public static String CLOSURE_formatting = null;
// public final static String FRAMEWORK_CLASS = "browser.ClosureFramework";
public final static String m_superCalledMarker = "___SUPER_HAS_BEEN_CALLED___ ";
public final static String THIS = "this";
public final static String SUPER = "super";
public final static String _SUPER = "_super";
public final static String THIS_SUPER = THIS + "." + SUPER;
public final static String JS_THIS = "this";
public final static Boolean m_useClosureLib = false;
public final static Boolean m_useSelfParameter = false;
public final static int OP_JS = OP_nop;
public final static String DEFAULT_PARAM_PREFIX = "_default_";
public final static String GETTER_PREFIX = "get_";
public final static String SETTER_PREFIX = "set_";
public final static String CTOR_NAME = "init";
public final static String EXTERN_INTERFACE_NAME = "IExtern";
public final static String SYMBOL_INTERFACE_NAME = "ISymbol";
public final static String FRAMEWORK_INTERFACE_NAME = "IFramework";
public final static String CLASS_NAME = "_CLASS";
public final static String SYMBOL_GET_LINKAGE = "getLinkage"; // see browser.ISymbol
public final static String SYMBOL_INIT = "init"; // see browser.ISymbol
public final static String SYMBOL_INSTANCE = "instance"; // see browser.ISymbol
public final static String GENERATE_CLASSINFO = "GenerateClassInfo"; // see browser.ISymbol
public final static String CONVERT_LOCAL_VARS_TO_MEMBERS = "ConvertLocalVarsToMembers";
// public final static String JS_STATIC_INITS = JS_FRAMEWORK_NAME + ".m_staticInits";
public final static String JS_RUN_STATIC_INITS = JS_FRAMEWORK_NAME + ".runStaticInits";
public final static String JS_SYMBOLS = JS_FRAMEWORK_NAME + ".m_symbols";
public final static String JS_CLASSES = JS_FRAMEWORK_NAME + ".classes";
public final static String JS_TESTCASES = JS_FRAMEWORK_NAME + ".testCases";
public final static String JS_INT_CLASS = JS_FRAMEWORK_NAME + ".intClass";
public final static String JS_UINT_CLASS = JS_FRAMEWORK_NAME + ".uintClass";
public final static String JS_EMPTY_FUNCTION = JS_FRAMEWORK_NAME + ".emptyFunction";
public final static String REQUIRED_TAG_MARKER = "__REQUIRED__";
public final static String EXTERN_METATAG = "Extern";
public final static String DATACLASS_METATAG = "DataClass";
public final static String TESTCASE_METATAG = "TestCase";
public final static String AS3XML = "browser.AS3XML";
public final static String AS3XMLList = "browser.AS3XMLList";
public final static String STATIC_INIT = "__static_init";
public final static byte CONSTANT_Namespace = 1;
public final static byte CONSTANT_PackageNs = 2;
public final static byte CONSTANT_PackageInternalNs = 3;
public final static byte CONSTANT_ProtectedNs = 4;
public final static byte CONSTANT_ExplicitNamespace = 5;
public final static byte CONSTANT_StaticProtectedNs = 6;
public final static byte CONSTANT_PrivateNs = 7;
public final static byte CONSTANT_ClassPrivateNS = 8;
private Set<String> m_packages = new TreeSet<String>();
private final ReadWriteLock m_packagesLock = new ReentrantReadWriteLock();
private Map<Name, Name> m_classes = new HashMap<Name, Name>();
private final ReadWriteLock m_classesLock = new ReentrantReadWriteLock();
private Map<Name, Set<Name>> m_interfaces = new HashMap<Name, Set<Name>>();
private final ReadWriteLock m_interfacesLock = new ReentrantReadWriteLock();
private Map<String, String> m_externs = new HashMap<String, String>();
private final ReadWriteLock m_externsLock = new ReentrantReadWriteLock();
private Map<String, String> m_varTypes = new HashMap<String, String>();
private final ReadWriteLock m_varTypesLock = new ReentrantReadWriteLock();
private Boolean m_verbose = false;
private final ReadWriteLock m_verboseLock = new ReentrantReadWriteLock();
private Object m_codeGenMonitor = new Object();
private long m_codeGenCounter = 0;
private final ReadWriteLock m_codeGenCounterLock = new ReentrantReadWriteLock();
private Set<Name> m_emittedClasses = new HashSet<Name>();
private final ReadWriteLock m_emittedClassesLock = new ReentrantReadWriteLock();
private Map<String, INamespaceDefinition> m_uriToNamespace = new HashMap<String, INamespaceDefinition>();
private Map<String, INamespaceDefinition> m_qnameToNamespace = new HashMap<String, INamespaceDefinition>();
private final ReadWriteLock m_uriToNamespaceLock = new ReentrantReadWriteLock();
private Map<String, String> m_classToSymbol = new HashMap<String, String>();
private final ReadWriteLock m_classToSymbolLock = new ReentrantReadWriteLock();
// private Map<IDefinition,Set<IDefinition>> m_dependencies = new HashMap<IDefinition,Set<IDefinition>>();
// private final ReadWriteLock m_dependenciesLock = new ReentrantReadWriteLock();
private Map<String, String> m_compilationUnitToJS = new HashMap<String, String>();
private final ReadWriteLock m_compilationUnitToJSLock = new ReentrantReadWriteLock();
private Map<SWFFrame, ICompilationUnit> m_swfFrameToCompilationUnit = new HashMap<SWFFrame, ICompilationUnit>();
private final ReadWriteLock m_swfFrameToCompilationUnitLock = new ReentrantReadWriteLock();
private Set<String> m_referencedDefinitions = new HashSet<String>();
private final ReadWriteLock m_referencedDefinitionsLock = new ReentrantReadWriteLock();
private Map<String, IDefinition> m_definitions = new HashMap<String, IDefinition>();
private final ReadWriteLock m_definitionsLock = new ReentrantReadWriteLock();
private Set<String> m_usedExterns = new HashSet<String>();
private final ReadWriteLock m_usedExternsLock = new ReentrantReadWriteLock();
private Set<String> m_scriptInfos = new HashSet<String>();
private final ReadWriteLock m_scriptInfosLock = new ReentrantReadWriteLock();
private Map<String, Integer> m_propertyNames = new HashMap<String, Integer>();
private final ReadWriteLock m_propertyNamesLock = new ReentrantReadWriteLock();
private Set<String> m_accessedPropertyNames = new HashSet<String>();
private final ReadWriteLock m_accessedPropertyNamesLock = new ReentrantReadWriteLock();
private Set<String> m_classInit = new HashSet<String>();
private final ReadWriteLock m_classInitLock = new ReentrantReadWriteLock();
private Map<String, String> m_pathToUUID = new HashMap<String, String>();
private final ReadWriteLock m_pathToUUIDLock = new ReentrantReadWriteLock();
private Set<String> m_encryptedJS = new HashSet<String>();
private final ReadWriteLock m_encryptedJSLock = new ReentrantReadWriteLock();
private Map<String, Set<String>> m_methods = new HashMap<String, Set<String>>();
private final ReadWriteLock m_methodsLock = new ReentrantReadWriteLock();
public void reset()
{
m_packages.clear();
m_classes.clear();
m_interfaces.clear();
m_externs.clear();
m_varTypes.clear();
m_verbose = false;
// m_codeGenMonitor
m_emittedClasses.clear();
m_uriToNamespace.clear();
m_qnameToNamespace.clear();
m_classToSymbol.clear();
// m_dependencies.clear();
m_compilationUnitToJS.clear();
m_swfFrameToCompilationUnit.clear();
m_referencedDefinitions.clear();
m_definitions.clear();
m_usedExterns.clear();
m_scriptInfos.clear();
m_propertyNames.clear();
m_accessedPropertyNames.clear();
m_classInit.clear();
// m_pathToUUID.clear();
m_encryptedJS.clear();
m_methods.clear();
}
/**
* @param m_packages the m_packages to set
*/
public void registerPackage(String packageName)
{
// TODO: generalize, avoid hard-coded "goog"
if (packageName != null && !packageName.isEmpty() && !packageName.startsWith("goog"))
{
m_packagesLock.writeLock().lock();
this.m_packages.add(packageName);
m_packagesLock.writeLock().unlock();
}
}
/**
* @return the m_packages
*/
public Boolean hasPackage(String packageName)
{
m_packagesLock.readLock().lock();
final Boolean val = m_packages.contains(packageName);
m_packagesLock.readLock().unlock();
return val;
}
/**
* @return the m_packages
*/
@SuppressWarnings("unchecked")
public Set<String> getPackages()
{
Set<String> packages = null;
m_packagesLock.readLock().lock();
Object clone = ((TreeSet<String>)m_packages).clone();
if (clone != null && clone instanceof Set<?>)
packages = (Set<String>)(clone);
m_packagesLock.readLock().unlock();
return packages;
}
/**
* @param m_varTypes the m_varTypes to set
*/
public void registerVarType(String varName, String varType)
{
m_varTypesLock.writeLock().lock();
this.m_varTypes.put(varName, varType);
m_varTypesLock.writeLock().unlock();
}
/**
* @return the m_varTypes
*/
public String getVarType(String varName)
{
m_varTypesLock.readLock().lock();
final String val = m_varTypes.get(varName);
m_varTypesLock.readLock().unlock();
return val;
}
public Boolean hasVarName(String varName)
{
m_varTypesLock.readLock().lock();
final Boolean val = m_varTypes.containsKey(varName);
m_varTypesLock.readLock().unlock();
return val;
}
/**
* @param m_classes the m_classes to set
*/
public void registerClass(Name className, Name superName)
{
m_classesLock.writeLock().lock();
this.m_classes.put(className, superName);
m_classesLock.writeLock().unlock();
}
/**
* @return the m_classes
*/
public Name getSuperClass(Name className)
{
m_classesLock.readLock().lock();
final Name val = m_classes.get(className);
m_classesLock.readLock().unlock();
return val;
}
public Boolean hasClass(Name className)
{
m_classesLock.readLock().lock();
final Boolean val = m_classes.containsKey(className);
m_classesLock.readLock().unlock();
return val;
}
public Map<String, String> getClassInfo()
{
// copying the whole m_classes is the only thing you can do
// if you want to stay thread safe.
Map<String, String> info = new HashMap<String, String>();
m_classesLock.readLock().lock();
Iterator<Map.Entry<Name, Name>> it = m_classes.entrySet().iterator();
while (it.hasNext())
{
Map.Entry<Name, Name> pair = it.next();
final Name _class = pair.getKey();
final Name _super = pair.getValue();
if (_super != null)
info.put(_class.getBaseName(), _super.getBaseName());
else
info.put(_class.getBaseName(), "Object");
}
m_classesLock.readLock().unlock();
return info;
}
public Set<Name> getClasses()
{
m_classesLock.readLock().lock();
Set<Name> info = new HashSet<Name>();
info.addAll(m_classes.keySet());
m_classesLock.readLock().unlock();
return info;
}
public void setVerbose(Boolean value)
{
m_verboseLock.writeLock().lock();
this.m_verbose = value;
m_verboseLock.writeLock().unlock();
}
public Boolean isVerbose()
{
m_verboseLock.readLock().lock();
final Boolean val = m_verbose;
m_verboseLock.readLock().unlock();
return val;
}
public void stdout(String s)
{
if (STDOUT != null)
{
m_verboseLock.writeLock().lock();
STDOUT.println(s);
m_verboseLock.writeLock().unlock();
}
}
public void stderr(String s)
{
if (STDERR != null)
{
m_verboseLock.writeLock().lock();
STDERR.println(s);
m_verboseLock.writeLock().unlock();
}
}
public void verboseMessage(String s)
{
if (isVerbose() && STDOUT != null)
{
m_verboseLock.writeLock().lock();
STDOUT.println(s);
m_verboseLock.writeLock().unlock();
}
}
public void beginCodeGen()
{
m_codeGenCounterLock.writeLock().lock();
m_codeGenCounter++;
m_codeGenCounterLock.writeLock().unlock();
}
public void endCodeGen()
{
m_codeGenCounterLock.writeLock().lock();
final long currentCounter = --m_codeGenCounter;
m_codeGenCounterLock.writeLock().unlock();
if (currentCounter == 0)
{
synchronized (m_codeGenMonitor)
{
m_codeGenMonitor.notifyAll();
}
}
}
/*
* private long getCodeGenCounter() {
* m_codeGenCounterLock.readLock().lock(); final long val =
* m_codeGenCounter; m_codeGenCounterLock.readLock().unlock(); return val; }
* private void waitUntilCodeGenHasFinished() throws InterruptedException {
* if( getCodeGenCounter() == 0 ) { synchronized (m_codeGenMonitor) {
* m_codeGenMonitor.wait(); } } }
*/
public void registerInterface(Name className, Name interfaceName)
{
m_interfacesLock.writeLock().lock();
Set<Name> interfaces = m_interfaces.get(className);
if (interfaces == null)
{
interfaces = new HashSet<Name>();
this.m_interfaces.put(className, interfaces);
}
interfaces.add(interfaceName);
m_interfacesLock.writeLock().unlock();
}
@SuppressWarnings("unchecked")
public Map<Name, Set<Name>> getAllInterfaces()
{
// copying the whole m_classes is the only thing you can do
// if you want to stay thread safe.
Map<Name, Set<Name>> info = new HashMap<Name, Set<Name>>();
m_interfacesLock.readLock().lock();
Iterator<Map.Entry<Name, Set<Name>>> it = m_interfaces.entrySet().iterator();
while (it.hasNext())
{
Map.Entry<Name, Set<Name>> pair = it.next();
final Name _class = pair.getKey();
final HashSet<Name> interfaces = (HashSet<Name>)pair.getValue();
info.put(_class, (Set<Name>)(interfaces.clone()));
}
m_interfacesLock.readLock().unlock();
return info;
}
public void registerExtern(Name name)
{
final IDefinition def = getDefinition(name);
if (def == null)
throw backend.createException("registerExtern: can't find definition for " + name.toString());
registerExtern(def);
}
public void registerExtern(IDefinition def)
{
final IMetaTag extern = def.getMetaTagByName(EXTERN_METATAG);
if (extern != null)
{
String externName = extern.getAttributeValue("name");
if (externName == null)
externName = def.getBaseName();
m_externsLock.writeLock().lock();
m_externs.put(def.getQualifiedName(), externName);
m_externsLock.writeLock().unlock();
}
}
public Boolean isExtern(String name)
{
m_externsLock.readLock().lock();
final Boolean val = m_externs.containsKey(name);
m_externsLock.readLock().unlock();
return val;
}
public String getExternName(String name)
{
m_externsLock.readLock().lock();
final String val = m_externs.get(name);
m_externsLock.readLock().unlock();
return val;
}
public Set<String> getExterns()
{
final Set<String> externs = new HashSet<String>();
m_externsLock.readLock().lock();
externs.addAll(m_externs.keySet());
m_externsLock.readLock().unlock();
return externs;
}
public void registerEmittedClass(Name classOrInterfaceName)
{
m_emittedClassesLock.writeLock().lock();
this.m_emittedClasses.add(classOrInterfaceName);
m_emittedClassesLock.writeLock().unlock();
}
public Boolean hasClassBeenEmitted(Name classOrInterfaceName)
{
m_emittedClassesLock.readLock().lock();
final Boolean val = m_emittedClasses.contains(classOrInterfaceName);
m_emittedClassesLock.readLock().unlock();
return val;
}
public void registerSymbol(String className, String symbolName)
{
m_classToSymbolLock.writeLock().lock();
this.m_classToSymbol.put(className, symbolName);
m_classToSymbolLock.writeLock().unlock();
}
public String getSymbol(String className)
{
m_classToSymbolLock.writeLock().lock();
final String symbol = this.m_classToSymbol.get(className);
m_classToSymbolLock.writeLock().unlock();
return symbol;
}
public Boolean hasSymbols()
{
m_classToSymbolLock.writeLock().lock();
final Boolean hasSymbols = !this.m_classToSymbol.isEmpty();
m_classToSymbolLock.writeLock().unlock();
return hasSymbols;
}
public List<String> getSymbols()
{
// copying the whole m_classes is the only thing you can do
// if you want to stay thread safe.
List<String> info = new ArrayList<String>();
m_classToSymbolLock.readLock().lock();
info.addAll(m_classToSymbol.values());
m_classToSymbolLock.readLock().unlock();
return info;
}
public void registerNamespace(String uri, INamespaceDefinition ns)
{
m_uriToNamespaceLock.writeLock().lock();
this.m_uriToNamespace.put(uri, ns);
this.m_qnameToNamespace.put(ns.getQualifiedName(), ns);
m_uriToNamespaceLock.writeLock().unlock();
}
public Map<String, INamespaceDefinition> getNamespaces()
{
// Copy the whole m_uriToNamespace for thread-safety
Map<String, INamespaceDefinition> namespaces = new HashMap<String, INamespaceDefinition>();
m_uriToNamespaceLock.writeLock().lock();
namespaces.putAll(m_uriToNamespace);
m_uriToNamespaceLock.writeLock().unlock();
return namespaces;
}
public INamespaceDefinition getNamespace(String uri)
{
m_uriToNamespaceLock.writeLock().lock();
final INamespaceDefinition ns = this.m_uriToNamespace.get(uri);
m_uriToNamespaceLock.writeLock().unlock();
return ns;
}
public INamespaceDefinition getNamespaceForQName(String qname)
{
m_uriToNamespaceLock.writeLock().lock();
final INamespaceDefinition ns = this.m_qnameToNamespace.get(qname);
m_uriToNamespaceLock.writeLock().unlock();
return ns;
}
/*
* // returns true if def1 depends on def2 private Boolean dependsOn(
* IDefinition def1, IDefinition def2 ) { Set<IDefinition> defs =
* m_dependencies.get(def2); if( defs.contains(def1) ) return true; for(
* IDefinition next: defs ) { if( dependsOn(def1, next) ) return true; }
* return false; } // workaround for Falcon bugs // Falcon's DependencyGraph
* does not work correctly for Definitions // implemented by SWCs. // def1
* depends on def2 public void addDependency( IDefinition def1, IDefinition
* def2 ) { if( def1 != def2 ) { m_dependenciesLock.writeLock().lock();
* Set<IDefinition> defs = m_dependencies.get(def1); if( defs == null ) {
* defs = new HashSet<IDefinition>(); m_dependencies.put( def1, defs ); }
* else { if( !defs.contains(def2) && dependsOn(def2, def1) ) throw new
* Error( "addDependency: circular dependencies!" ); } defs.add(def2);
* m_dependenciesLock.writeLock().unlock(); } } public Set<IDefinition>
* getDependencies( IDefinition def ) {
* m_dependenciesLock.writeLock().lock(); final Set<IDefinition> defs =
* m_dependencies.get(def); m_dependenciesLock.writeLock().unlock(); return
* defs; }
*/
public void registerJavaScript(String className, String jsCode)
{
m_compilationUnitToJSLock.writeLock().lock();
m_compilationUnitToJS.put(className, jsCode);
m_compilationUnitToJSLock.writeLock().unlock();
}
public void registerJavaScript(Map<String, String> classNameToJS)
{
m_compilationUnitToJSLock.writeLock().lock();
m_compilationUnitToJS.putAll(classNameToJS);
m_compilationUnitToJSLock.writeLock().unlock();
}
public Boolean hasJavaScript(String className)
{
m_compilationUnitToJSLock.writeLock().lock();
final Boolean found = m_compilationUnitToJS.containsKey(className);
m_compilationUnitToJSLock.writeLock().unlock();
return found;
}
public String getJavaScript(String className)
{
m_compilationUnitToJSLock.writeLock().lock();
final String jsCode = m_compilationUnitToJS.get(className);
m_compilationUnitToJSLock.writeLock().unlock();
return jsCode;
}
public void registerSWFFrame(SWFFrame frame, ICompilationUnit cu)
{
m_swfFrameToCompilationUnitLock.writeLock().lock();
m_swfFrameToCompilationUnit.put(frame, cu);
m_swfFrameToCompilationUnitLock.writeLock().unlock();
}
public ICompilationUnit getCompilationUnit(SWFFrame frame)
{
m_swfFrameToCompilationUnitLock.writeLock().lock();
final ICompilationUnit cu = m_swfFrameToCompilationUnit.get(frame);
m_swfFrameToCompilationUnitLock.writeLock().unlock();
return cu;
}
public void registerReferencedDefinition(String name)
{
m_referencedDefinitionsLock.writeLock().lock();
m_referencedDefinitions.add(name);
m_referencedDefinitionsLock.writeLock().unlock();
}
public Boolean isReferencedDefinition(String name)
{
m_referencedDefinitionsLock.readLock().lock();
final Boolean val = m_referencedDefinitions.contains(name);
m_referencedDefinitionsLock.readLock().unlock();
return val;
}
public void registerDefinition(IDefinition def)
{
m_definitionsLock.writeLock().lock();
final String qName = def.getQualifiedName();
this.m_definitions.put(qName, def);
m_definitionsLock.writeLock().unlock();
// register this definition as an extern if necessary.
final IMetaTag extern = def.getMetaTagByName(JSSharedData.EXTERN_METATAG);
if (extern != null)
registerExtern(def);
}
public IDefinition getDefinition(String qualifiedName)
{
m_definitionsLock.readLock().lock();
final IDefinition val = m_definitions.get(qualifiedName);
m_definitionsLock.readLock().unlock();
return val;
}
public IDefinition getDefinition(Name name)
{
m_definitionsLock.readLock().lock();
IDefinition val = null;
final String baseName = name.getBaseName();
if (baseName != null)
{
final Nsset nsset = name.getQualifiers();
if (nsset != null)
{
for (Namespace ns : nsset)
{
String defName = ns.getName();
if (!defName.isEmpty())
defName += ".";
defName += name.getBaseName();
val = m_definitions.get(defName);
if (val != null)
break;
}
}
}
if (val == null)
val = m_definitions.get(baseName);
m_definitionsLock.readLock().unlock();
return val;
}
public String getQualifiedName(Name name)
{
final IDefinition def = getDefinition(name);
if (def != null)
return def.getQualifiedName();
return null;
}
public void registerUsedExtern(String name)
{
m_usedExternsLock.writeLock().lock();
m_usedExterns.add(name);
m_usedExternsLock.writeLock().unlock();
}
public Boolean isUsedExtern(String name)
{
m_usedExternsLock.readLock().lock();
final Boolean val = m_usedExterns.contains(name);
m_usedExternsLock.readLock().unlock();
return val;
}
public Set<String> getUsedExterns()
{
final Set<String> externs = new HashSet<String>();
m_scriptInfosLock.readLock().lock();
externs.addAll(m_scriptInfos);
m_scriptInfosLock.readLock().unlock();
return externs;
}
public void registerScriptInfo(String name)
{
m_scriptInfosLock.writeLock().lock();
m_scriptInfos.add(name);
m_scriptInfosLock.writeLock().unlock();
}
public Set<String> getScriptInfos()
{
final Set<String> scriptInfos = new HashSet<String>();
m_scriptInfosLock.readLock().lock();
scriptInfos.addAll(m_scriptInfos);
m_scriptInfosLock.readLock().unlock();
return scriptInfos;
}
public void registerPropertyName(String name)
{
m_propertyNamesLock.writeLock().lock();
if (m_propertyNames.containsKey(name))
{
final Integer uses = m_propertyNames.get(name);
m_propertyNames.put(name, uses + 1);
}
else
{
m_propertyNames.put(name, 1);
}
m_propertyNamesLock.writeLock().unlock();
}
public Boolean isUniquePropertyName(String name)
{
Boolean isUnique = true;
m_propertyNamesLock.readLock().lock();
if (m_propertyNames.containsKey(name))
{
final Integer uses = m_propertyNames.get(name);
if (uses > 1)
isUnique = false;
}
m_propertyNamesLock.readLock().unlock();
return isUnique;
}
// called whenever we have to emit adobe.get/set/call property.
public void registerAccessedPropertyName(String name)
{
m_accessedPropertyNamesLock.writeLock().lock();
m_accessedPropertyNames.add(name);
m_accessedPropertyNamesLock.writeLock().unlock();
}
public Boolean isAccessedPropertyName(String name)
{
m_accessedPropertyNamesLock.readLock().lock();
final Boolean val = m_accessedPropertyNames.contains(name);
m_accessedPropertyNamesLock.readLock().unlock();
return val;
}
public static Boolean usingAdvancedOptimizations()
{
return CLOSURE_compilation_level.equals("ADVANCED_OPTIMIZATIONS");
}
// called whenever we have to emit adobe.get/set/call property.
public void registerClassInit(String fullClassName)
{
if (fullClassName != null && !fullClassName.isEmpty())
{
m_classInitLock.writeLock().lock();
m_classInit.add(fullClassName);
m_classInitLock.writeLock().unlock();
}
}
public Boolean hasClassInit(String fullClassName)
{
m_classInitLock.readLock().lock();
final Boolean val = m_classInit.contains(fullClassName);
m_classInitLock.readLock().unlock();
return val;
}
public Boolean hasAnyClassInit()
{
m_classInitLock.readLock().lock();
final Boolean val = m_classInit.isEmpty();
m_classInitLock.readLock().unlock();
return !val;
}
public void registerUUID(String path, String uuid)
{
m_pathToUUIDLock.writeLock().lock();
m_pathToUUID.put(path, uuid);
m_pathToUUIDLock.writeLock().unlock();
}
public String getUUID(String path)
{
m_pathToUUIDLock.readLock().lock();
final String val = m_pathToUUID.get(path);
m_pathToUUIDLock.readLock().unlock();
return val;
}
public void registerEncryptedJS(String name)
{
m_encryptedJSLock.writeLock().lock();
m_encryptedJS.add(name);
m_encryptedJSLock.writeLock().unlock();
}
public Boolean hasEncryptedJS(String name)
{
m_encryptedJSLock.readLock().lock();
final Boolean val = m_encryptedJS.contains(name);
m_encryptedJSLock.readLock().unlock();
return val;
}
public Boolean hasAnyEncryptedJS()
{
m_encryptedJSLock.readLock().lock();
final Boolean val = !m_encryptedJS.isEmpty();
m_encryptedJSLock.readLock().unlock();
return val;
}
public void registerMethod(String methodName, String className)
{
m_methodsLock.writeLock().lock();
Set<String> classes = m_methods.get(methodName);
if (classes == null)
{
classes = new HashSet<String>();
m_methods.put(methodName, classes);
}
classes.add(className);
m_methodsLock.writeLock().unlock();
}
// poor man's type inference.
public void registerMethods(ICompilerProject project, IMemberedDefinition memberedDef)
{
final String className = memberedDef.getQualifiedName();
final ASDefinitionFilter memberFilter = new ASDefinitionFilter(
ClassificationValue.FUNCTIONS, SearchScopeValue.INHERITED_MEMBERS,
AccessValue.ALL, memberedDef);
for (IDefinition member : MemberedDefinitionUtils.getAllMembers(memberedDef, project, memberFilter))
{
/*
* class method registered as eventListener gets global when class
* instance is in an array
* http://watsonexp.corp.adobe.com/#bug=3040108 We need register
* only methods with unique signatures. In other words overridden
* methods must be excluded.
*/
if (member instanceof IFunctionDefinition && !member.isOverride())
{
final INamespaceDefinition ns = member.resolveNamespace(project);
if (ns != null && ns.isPublicOrInternalNamespace())
registerMethod(member.getBaseName(), className);
}
}
}
// poor man's type inference.
public Set<IFunctionDefinition> getMethods(ICompilerProject project, String methodName)
{
Set<IFunctionDefinition> defs = new HashSet<IFunctionDefinition>();
m_methodsLock.readLock().lock();
final Set<String> classes = m_methods.get(methodName);
if (classes != null)
{
for (String className : classes)
{
final IDefinition def = getDefinition(className);
if (def != null && def instanceof IMemberedDefinition)
{
final ASDefinitionFilter memberFilter = new ASDefinitionFilter(
ClassificationValue.FUNCTIONS, SearchScopeValue.INHERITED_MEMBERS,
AccessValue.ALL, def);
final IMemberedDefinition memberedDef = (IMemberedDefinition)def;
final IDefinition mdef = MemberedDefinitionUtils.getMemberByName(
memberedDef, project, methodName, memberFilter);
if (mdef instanceof IFunctionDefinition)
{
final IFunctionDefinition fdef = (IFunctionDefinition)mdef;
defs.add(fdef);
}
}
}
}
m_methodsLock.readLock().unlock();
return defs;
}
}