| /* |
| * |
| * 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 flex2.compiler; |
| |
| import flex2.compiler.common.MxmlConfiguration; |
| import flex2.compiler.common.PathResolver; |
| import flex2.compiler.common.SinglePathResolver; |
| import flex2.compiler.io.InMemoryFile; |
| import flex2.compiler.io.VirtualFile; |
| import flex2.compiler.swc.SwcScript; |
| import flex2.compiler.util.LineNumberMap; |
| import flex2.compiler.util.LocalLogger; |
| import flex2.compiler.util.MimeMappings; |
| import flex2.compiler.util.MultiName; |
| import flex2.compiler.util.QName; |
| import flex2.compiler.util.ThreadLocalToolkit; |
| import flex2.tools.oem.ApplicationCache; |
| import macromedia.asc.semantics.TypeValue; |
| import macromedia.asc.util.Context; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.*; |
| import java.util.Map.Entry; |
| |
| /** |
| * This class represents the information associated with a single file |
| * while it's being compiled. This information includes the |
| * <code>pathRoot</code>, the <code>relativePath</code>, the |
| * <code>shortName</code>, which is often the class name, the owner, |
| * which specifies where the Source came from, and whether the |
| * <code>Source</code> is internal, root, and debuggable. |
| */ |
| public final class Source implements Comparable<Source> |
| { |
| // used by flex2.compiler.i18n.I18nCompiler, InterfaceCompiler and ImplementationCompiler |
| public Source(VirtualFile file, Source original) |
| { |
| this(file, original.pathRoot, original.relativePath, original.shortName, original.owner, original.isInternal, original.isRoot, original.isDebuggable); |
| this.delegate = original; |
| } |
| |
| // used by InterfaceCompiler.createInlineComponentUnit(). Note the owner will be set |
| // later by the ResourceContainer when this is passed into addResource() by |
| // CompilerAPI.addGeneratedSources(). |
| public Source(VirtualFile file, Source original, String shortName, boolean isInternal, boolean isRoot) |
| { |
| this(file, original.pathRoot, original.relativePath, shortName, null, isInternal, isRoot, true); |
| this.delegate = original; |
| } |
| |
| // used by FileSpec |
| public Source(VirtualFile file, String relativePath, String shortName, Object owner, boolean isInternal, boolean isRoot) |
| { |
| this(file, null, relativePath, shortName, owner, isInternal, isRoot, true); |
| } |
| |
| // used by SourceList and SourcePath |
| public Source(VirtualFile file, VirtualFile pathRoot, String relativePath, String shortName, Object owner, boolean isInternal, boolean isRoot) |
| { |
| this(file, pathRoot, relativePath, shortName, owner, isInternal, isRoot, true); |
| } |
| |
| // used by StylesContainer, CompilerSwcContext, EmbedEvaluator, DataBindingExtension and PreLink |
| public Source(VirtualFile file, String relativePath, String shortName, Object owner, boolean isInternal, boolean isRoot, boolean isDebuggable) |
| { |
| this(file, null, relativePath, shortName, owner, isInternal, isRoot, isDebuggable); |
| } |
| |
| Source(VirtualFile file, VirtualFile pathRoot, String relativePath, String shortName, Object owner, boolean isInternal, boolean isRoot, boolean isDebuggable) |
| { |
| this.file = file; |
| this.pathRoot = pathRoot; |
| this.relativePath = relativePath; |
| this.shortName = shortName; |
| this.owner = owner; |
| this.isInternal = isInternal; |
| this.isRoot = isRoot; |
| this.isDebuggable = isDebuggable; |
| |
| if (file != null) |
| { |
| fileTime = file.getLastModified(); |
| } |
| |
| fileIncludeTimes = new HashMap<VirtualFile, Long>(4); |
| } |
| |
| private VirtualFile file; |
| private VirtualFile pathRoot; |
| // 'resolver' doesn't need persistence because it's constructed from pathRoot. |
| private PathResolver resolver; |
| private String relativePath, shortName; |
| private Object owner; |
| private boolean isInternal; |
| private boolean isRoot; |
| private boolean isDebuggable; |
| private boolean isPreprocessed; |
| |
| private CompilationUnit unit; |
| |
| private long fileTime; |
| private Map<VirtualFile, Long> fileIncludeTimes; |
| |
| // 1. path resolution |
| // 2. backing file |
| // 3. source fragments |
| private Source delegate; |
| |
| /** |
| * This is a per-Source/CompilationUnit logger. The |
| * ThreadLocalToolkit logger is a per-compile logger. This logger |
| * is usually wired to the ThreadLocalToolkit logger. During the |
| * life of a Source, this logger be nulled out, when it's no |
| * longer needed to save memory. If the Source is reused again, a |
| * new LocalLogger is created by CompilerAPI.preprocess(). |
| */ |
| private LocalLogger logger; |
| |
| private Map<String, Object> fragments; |
| private Map<String, LineNumberMap> fragmentLineMaps; |
| |
| private AssetInfo assetInfo; |
| |
| public int lineCount; |
| |
| private int reuseCount = 0; |
| private int totalDependentCount; |
| |
| public CompilationUnit newCompilationUnit(Object syntaxTree, CompilerContext context) |
| { |
| unit = new CompilationUnit(this, syntaxTree, context); |
| unit.setStandardDefs(ThreadLocalToolkit.getStandardDefs()); |
| return unit; |
| } |
| |
| public CompilationUnit getCompilationUnit() |
| { |
| return unit; |
| } |
| |
| void removeCompilationUnit() |
| { |
| // CompilationUnit's created from SwcScript's can't be easily |
| // recreated, so just remove the type information. The |
| // alternative is to factor out the CompilationUnit creation |
| // from CompilerSwcContext.createSource() and modify |
| // AbcCompiler.parse1() to call it when the CompilationUnit is |
| // null. |
| if (isSwcScriptOwner()) |
| { |
| unit.removeTypeInfo(); |
| } |
| else |
| { |
| unit = null; |
| } |
| |
| fileTime = file.getLastModified(); |
| logger = null; |
| isPreprocessed = false; |
| |
| fileIncludeTimes.clear(); |
| |
| delegate = null; |
| resolver = null; |
| |
| if (fragments != null) |
| { |
| fragments.clear(); |
| fragmentLineMaps.clear(); |
| } |
| } |
| |
| public void setAssetInfo(AssetInfo assetInfo) |
| { |
| this.assetInfo = assetInfo; |
| } |
| |
| void setPreprocessed() |
| { |
| isPreprocessed = true; |
| } |
| |
| boolean isPreprocessed() |
| { |
| return isPreprocessed; |
| } |
| |
| void setLogger(LocalLogger logger) |
| { |
| this.logger = logger; |
| } |
| |
| public LocalLogger getLogger() |
| { |
| return logger; |
| } |
| |
| public void disconnectLogger() |
| { |
| if (logger != null && logger.warningCount() == 0 && logger.errorCount() == 0) |
| { |
| logger = null; |
| } |
| else if (logger != null) |
| { |
| // if warning/error exists, keep the logger and just disconnect it from the original logger. |
| logger.disconnect(); |
| } |
| } |
| |
| boolean hasError() |
| { |
| return logger != null && logger.errorCount() > 0; |
| } |
| |
| public Object getOwner() |
| { |
| return owner; |
| } |
| |
| // C: do not make this public; only used by ResourceContainer. |
| void setOwner(Object owner) |
| { |
| this.owner = owner; |
| } |
| |
| public boolean isSourcePathOwner() |
| { |
| return owner != null && owner instanceof SourcePath && !isResourceBundlePathOwner(); |
| } |
| |
| public boolean isSourceListOwner() |
| { |
| return owner != null && owner instanceof SourceList; |
| } |
| |
| public boolean isFileSpecOwner() |
| { |
| return owner != null && owner instanceof FileSpec; |
| } |
| |
| public boolean isCompilerSwcContextOwner() |
| { |
| return owner != null && owner instanceof CompilerSwcContext; |
| } |
| |
| public boolean isSwcScriptOwner() |
| { |
| return owner != null && owner instanceof SwcScript; |
| } |
| |
| public boolean isResourceContainerOwner() |
| { |
| return owner != null && owner instanceof ResourceContainer; |
| } |
| |
| public boolean isResourceBundlePathOwner() |
| { |
| return owner != null && owner instanceof ResourceBundlePath; |
| } |
| |
| public boolean isInternal() |
| { |
| return isInternal; |
| } |
| |
| public boolean isEntryPoint() |
| { |
| return isFileSpecOwner(); |
| } |
| |
| public boolean isRoot() |
| { |
| return isRoot; |
| } |
| |
| public boolean isDebuggable() |
| { |
| return isDebuggable; |
| } |
| |
| public boolean isCompiled() |
| { |
| return unit != null && unit.isBytecodeAvailable(); |
| } |
| |
| public boolean isUpdated() |
| { |
| long lastModified = file.getLastModified(); |
| |
| if (lastModified != fileTime) |
| { |
| return true; |
| } |
| else |
| { |
| for (Entry<VirtualFile, Long> entry : fileIncludeTimes.entrySet()) |
| { |
| if (entry.getKey().getLastModified() != entry.getValue().longValue()) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| } |
| |
| boolean isUpdated(Source source) |
| { |
| boolean result = false; |
| |
| if (assetInfo != null) |
| { |
| if (assetInfo.getArgs().size() != source.assetInfo.getArgs().size()) |
| { |
| result = true; |
| } |
| else |
| { |
| for (Iterator i = assetInfo.getArgs().entrySet().iterator(); i.hasNext() && !result;) |
| { |
| Entry entry = (Entry) i.next(); |
| String key = (String) entry.getKey(); |
| String value = (String) entry.getValue(); |
| |
| if (!value.equals(Transcoder.COLUMN) && |
| !value.equals(Transcoder.LINE) && |
| !value.equals(source.assetInfo.getArgs().get(key))) |
| { |
| result = true; |
| } |
| } |
| } |
| } |
| |
| return result; |
| } |
| |
| public boolean exists() |
| { |
| return file.getLastModified() > 0; |
| } |
| |
| public String getName() |
| { |
| return file.getName(); |
| } |
| |
| public String getNameForReporting() |
| { |
| return file.getNameForReporting(); |
| } |
| |
| // C: This is temporary... only use it when you need to set asc Context.setPath |
| public String getParent() |
| { |
| return file.getParent(); |
| } |
| |
| public long size() |
| { |
| return file.size(); |
| } |
| |
| public InputStream getInputStream() throws IOException |
| { |
| return file.getInputStream(); |
| } |
| |
| public byte[] toByteArray() throws IOException |
| { |
| return file.toByteArray(); |
| } |
| |
| public boolean isTextBased() |
| { |
| return file.isTextBased(); |
| } |
| |
| public String getInputText() |
| { |
| return file.toString(); |
| } |
| |
| public String getMimeType() |
| { |
| return file.getMimeType(); |
| } |
| |
| public long getLastModified() |
| { |
| return fileTime; |
| } |
| |
| public VirtualFile resolve(String include) |
| { |
| return getPathResolver().resolve(include); |
| } |
| |
| public PathResolver getPathResolver() |
| { |
| if (resolver == null) |
| { |
| resolver = new PathResolver(); |
| resolver.addSinglePathResolver(new Resolver(delegate != null ? delegate.getPathResolver() : null, file, pathRoot)); |
| resolver.addSinglePathResolver(ThreadLocalToolkit.getPathResolver()); |
| } |
| |
| return resolver; |
| } |
| |
| static class Resolver implements SinglePathResolver |
| { |
| Resolver(PathResolver delegate, VirtualFile file, VirtualFile pathRoot) |
| { |
| this.delegate = delegate; |
| this.file = file; |
| this.pathRoot = pathRoot; |
| } |
| |
| private PathResolver delegate; |
| private VirtualFile file, pathRoot; |
| |
| public VirtualFile resolve(String relative) |
| { |
| VirtualFile f = null; |
| |
| if (relative != null) |
| { |
| // delegate.resolve() before this.resolve() |
| if (delegate != null) |
| { |
| f = delegate.resolve(relative); |
| } |
| else |
| { |
| // A leading slash harks back to the Servlet days |
| // and meant look in the context root, so if we |
| // see a leading slash, we skip looking relative |
| // to the file. |
| if (!relative.startsWith("/")) |
| { |
| f = file.resolve(relative); |
| } |
| |
| if ((f == null) && (pathRoot != null)) |
| { |
| // See above note about about a leading slash. |
| // We used to blindly chop off the leading |
| // character and many existing apps are now |
| // dependent on the broken behavior. See the |
| // performance testsuite for examples. |
| if (relative.startsWith("/") || |
| (ThreadLocalToolkit.getCompatibilityVersion() < MxmlConfiguration.VERSION_4_5)) |
| { |
| f = pathRoot.resolve(relative.substring(1)); |
| } |
| } |
| } |
| } |
| |
| return f; |
| } |
| } |
| |
| public void setPathResolver(PathResolver pathResolver) |
| { |
| this.resolver = pathResolver; |
| } |
| |
| public VirtualFile getBackingFile() |
| { |
| return (delegate == null)? file : delegate.getBackingFile(); |
| } |
| |
| public String getRelativePath() |
| { |
| // C: should be /-separated (no backslash) |
| return relativePath; |
| } |
| |
| public String getShortName() |
| { |
| return shortName; |
| } |
| |
| public VirtualFile getPathRoot() |
| { |
| return pathRoot; |
| } |
| |
| public void addFileIncludes(Source s) |
| { |
| fileIncludeTimes.putAll(s.fileIncludeTimes); |
| } |
| |
| public boolean addFileInclude(String path) |
| { |
| VirtualFile f = resolve(path); |
| |
| return addFileInclude(f); |
| } |
| |
| public boolean addFileInclude(VirtualFile f) |
| { |
| if (f != null) |
| { |
| if (!fileIncludeTimes.containsKey(f)) |
| { |
| fileIncludeTimes.put(f, f.getLastModified()); |
| } |
| |
| if (delegate != null) |
| { |
| delegate.addFileInclude(f); |
| } |
| |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| public Iterator<VirtualFile> getFileIncludes() |
| { |
| return fileIncludeTimes.keySet().iterator(); |
| } |
| |
| /** |
| * Returns a copy. |
| */ |
| public Set<VirtualFile> getFileIncludesSet() |
| { |
| return new HashSet<VirtualFile>(fileIncludeTimes.keySet()); |
| } |
| |
| /** |
| * Returns a copy. |
| */ |
| public Map<VirtualFile, Long> getFileIncludeTimes() |
| { |
| return new HashMap<VirtualFile, Long>(fileIncludeTimes); |
| } |
| |
| public boolean isIncludedFile(String name) |
| { |
| for (VirtualFile f : fileIncludeTimes.keySet()) |
| { |
| if (f.getName().equals(name) || f.getNameForReporting().equals(name)) |
| { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| public Iterator<VirtualFile> getUpdatedFileIncludes() |
| { |
| List<VirtualFile> updated = null; |
| |
| for (VirtualFile f : fileIncludeTimes.keySet()) |
| { |
| long ts = fileIncludeTimes.get(f).longValue(); |
| if (f.getLastModified() != ts) |
| { |
| if (updated == null) |
| { |
| updated = new ArrayList<VirtualFile>(fileIncludeTimes.size()); |
| } |
| updated.add(f); |
| } |
| } |
| |
| return updated == null ? null : updated.iterator(); |
| } |
| |
| public int getFileIncludeSize() |
| { |
| return fileIncludeTimes.size(); |
| } |
| |
| long getFileIncludeTime(VirtualFile f) |
| { |
| return fileIncludeTimes.get(f).longValue(); |
| } |
| |
| public long getFileTime() |
| { |
| return fileTime; |
| } |
| |
| public void setFileTime(long fileTime) |
| { |
| this.fileTime = fileTime; |
| } |
| |
| public void addSourceFragment(String n, Object f, LineNumberMap m) |
| { |
| if (fragments == null) |
| { |
| fragments = new HashMap<String, Object>(); |
| fragmentLineMaps = new HashMap<String, LineNumberMap>(); |
| } |
| |
| fragments.put(n, f); |
| |
| if (m != null) |
| { |
| fragmentLineMaps.put(n, m); |
| } |
| } |
| |
| public Object getSourceFragment(String n) |
| { |
| // this.fragment before delegate.fragment |
| Object obj = (fragments == null) ? null : fragments.get(n); |
| if (obj == null && delegate != null) |
| { |
| return delegate.getSourceFragment(n); |
| } |
| else |
| { |
| return obj; |
| } |
| } |
| |
| public Collection<LineNumberMap> getSourceFragmentLineMaps() |
| { |
| if (fragmentLineMaps != null) |
| { |
| return fragmentLineMaps.values(); |
| } |
| else if (delegate != null) |
| { |
| return delegate.getSourceFragmentLineMaps(); |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| void clearSourceFragments() |
| { |
| fragments = null; |
| fragmentLineMaps = null; |
| |
| if (delegate != null) |
| { |
| delegate.clearSourceFragments(); |
| } |
| } |
| |
| /** |
| * Used by the web tier for dependency tracking. |
| * |
| * returns the last modified time of the source file itself |
| * without taking last modified time of any dependent files into account |
| * |
| * does not return a last modified time for in-memory files |
| */ |
| public long getRawLastModified() |
| { |
| if (isSwcScriptOwner()) |
| { |
| return ((SwcScript) owner).getLibrary().getSwcCreationTime(); |
| } |
| else if (isFileSpecOwner() || isSourceListOwner() || isSourcePathOwner()) |
| { |
| return fileTime; |
| } |
| else // if (isResourceBundlePathOwner() || isResourceContainerOwner()) |
| { |
| return -1; |
| } |
| } |
| |
| /** |
| * Used by the web tier for dependency tracking. |
| */ |
| public String getRawLocation() |
| { |
| if (isSwcScriptOwner()) |
| { |
| return ((SwcScript) owner).getLibrary().getSwcLocation(); |
| } |
| else |
| { |
| return getName(); |
| } |
| } |
| |
| public int compareTo(Source source) |
| { |
| return getName().compareTo(source.getName()); |
| } |
| |
| public int hashCode() |
| { |
| return getName().hashCode(); |
| } |
| |
| public boolean equals(Object object) |
| { |
| if (object instanceof Source) |
| { |
| Source s = (Source) object; |
| return s.owner == owner && s.getName().equals(getName()) && s.getRelativePath().equals(getRelativePath()); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| public void close() |
| { |
| file.close(); |
| } |
| |
| /** |
| * Make a copy of this Source object. Dependencies are multinames in the clone. |
| */ |
| public Source copy() |
| { |
| if (unit != null && unit.isDone()) |
| { |
| // copying Source |
| VirtualFile f = new InMemoryFile(unit.getByteCodes(), getName(), MimeMappings.ABC, fileTime); |
| Source s = new Source(f, pathRoot, relativePath, shortName, owner, isInternal, isRoot, isDebuggable); |
| |
| s.fileIncludeTimes.putAll(fileIncludeTimes); |
| s.logger = logger; |
| |
| // copying CompilationUnit |
| CompilationUnit u = s.newCompilationUnit(null, new CompilerContext()); |
| |
| copyCompilationUnit(unit, u, true); |
| |
| return s; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| /** |
| * This method copies all the guts of one CompilationUnit into |
| * another. It was formerly called copyMetaData(), but it grew to |
| * include more than just metadata, so it was renamed. |
| */ |
| public static void copyCompilationUnit(CompilationUnit fromUnit, CompilationUnit toUnit, |
| boolean useHistories) |
| { |
| toUnit.topLevelDefinitions.addAll(fromUnit.topLevelDefinitions); |
| |
| if (useHistories) |
| { |
| // For non-SwcScript based CompilationUnit's we want to |
| // copy all the MultiName dependencies from the old |
| // CompilationUnit's history into the new CompilationUnit, |
| // so they can be resolved again. This covers the case |
| // where an ambiguity was introduced between incremental |
| // compiles. |
| toUnit.inheritance.addAll(fromUnit.inheritanceHistory.keySet()); |
| toUnit.types.addAll(fromUnit.typeHistory.keySet()); |
| toUnit.namespaces.addAll(fromUnit.namespaceHistory.keySet()); |
| toUnit.expressions.addAll(fromUnit.expressionHistory.keySet()); |
| } |
| else |
| { |
| // CompilationUnit's from SwcScript's get there |
| // dependencies from the catalog.xml file, so we copy them |
| // directly to the new CompilationUnit. |
| toUnit.inheritance.addAll(fromUnit.inheritance); |
| toUnit.types.addAll(fromUnit.types); |
| toUnit.namespaces.addAll(fromUnit.namespaces); |
| toUnit.expressions.addAll(fromUnit.expressions); |
| } |
| |
| toUnit.inheritanceHistory = fromUnit.inheritanceHistory; |
| toUnit.typeHistory = fromUnit.typeHistory; |
| toUnit.namespaceHistory = fromUnit.namespaceHistory; |
| toUnit.expressionHistory = fromUnit.expressionHistory; |
| |
| toUnit.setSignatureChecksum(fromUnit.getSignatureChecksum()); |
| |
| if (fromUnit.hasAssets()) |
| { |
| toUnit.getAssets().addAll(fromUnit.getAssets()); |
| } |
| |
| toUnit.auxGenerateInfo = fromUnit.auxGenerateInfo; |
| |
| // These values are not type info dependent, so always copy them over. |
| toUnit.icon = fromUnit.icon; |
| toUnit.iconFile = fromUnit.iconFile; |
| |
| if (fromUnit.hasTypeInfo) |
| { |
| // There is no need to persist these properties because they exists as AS3 metadata in abc[], which |
| // PersistenceStore always persists. |
| toUnit.styles = fromUnit.styles; |
| toUnit.typeInfo = fromUnit.typeInfo; |
| toUnit.hasTypeInfo = true; |
| toUnit.classTable.putAll(fromUnit.classTable); |
| toUnit.swfMetaData = fromUnit.swfMetaData; |
| toUnit.loaderClass = fromUnit.loaderClass; |
| toUnit.loaderClassBase = fromUnit.loaderClassBase; |
| toUnit.extraClasses.addAll(fromUnit.extraClasses); |
| toUnit.addAccessibilityClasses(fromUnit); |
| toUnit.licensedClassReqs.putAll(fromUnit.licensedClassReqs); |
| toUnit.remoteClassAliases.putAll(fromUnit.remoteClassAliases); |
| toUnit.effectTriggers.putAll(fromUnit.effectTriggers); |
| toUnit.mixins.addAll(fromUnit.mixins); |
| toUnit.resourceBundleHistory.addAll(fromUnit.resourceBundleHistory); |
| toUnit.bytes = fromUnit.bytes; |
| } |
| } |
| |
| /** |
| * Creates a Source object, given a VirtualFile |
| */ |
| static Source newSource(VirtualFile f, long fileTime, VirtualFile pathRoot, String relativePath, String shortName, Object owner, |
| boolean isInternal, boolean isRoot, boolean isDebuggable, Set<VirtualFile> includes, Map<VirtualFile, Long> includeTimes, |
| LocalLogger logger) |
| { |
| Source s = new Source(f, pathRoot, relativePath, shortName, owner, isInternal, isRoot, isDebuggable); |
| s.fileTime = fileTime; |
| s.fileIncludeTimes.putAll(includeTimes); |
| s.logger = logger; |
| |
| return s; |
| } |
| |
| /** |
| * Creates a Source object, given an abc[] |
| */ |
| static Source newSource(byte[] abc, String name, long fileTime, VirtualFile pathRoot, String relativePath, String shortName, Object owner, |
| boolean isInternal, boolean isRoot, boolean isDebuggable, Set<VirtualFile> includes, Map<VirtualFile, Long> includeTimes, |
| LocalLogger logger) |
| { |
| VirtualFile f = new InMemoryFile(abc, name, MimeMappings.ABC, fileTime); |
| return newSource(f, fileTime, pathRoot, relativePath, shortName, owner, isInternal, isRoot, isDebuggable, |
| includes, includeTimes, logger); |
| } |
| |
| /** |
| * Populates a Source object. |
| */ |
| static Source populateSource(Source s, long fileTime, VirtualFile pathRoot, String relativePath, String shortName, Object owner, |
| boolean isInternal, boolean isRoot, boolean isDebuggable, Set<VirtualFile> includes, Map<VirtualFile, Long> includeTimes, |
| LocalLogger logger) |
| { |
| assert s != null; |
| |
| s.fileTime = fileTime; |
| s.pathRoot = pathRoot; |
| s.relativePath = relativePath; |
| s.shortName = shortName; |
| s.owner = owner; |
| s.isInternal = isInternal; |
| s.isRoot = isRoot; |
| s.isDebuggable = isDebuggable; |
| s.fileIncludeTimes.putAll(includeTimes); |
| s.logger = logger; |
| |
| return s; |
| } |
| |
| public void reused() |
| { |
| reuseCount++; |
| } |
| |
| public int getReuseCount() |
| { |
| return reuseCount; |
| } |
| |
| public int getTotalDependentCount() |
| { |
| return totalDependentCount; |
| } |
| |
| public void setTotalDependentCount(int totalDependentCount) |
| { |
| this.totalDependentCount = totalDependentCount; |
| } |
| |
| public String toString() |
| { |
| return getName(); |
| } |
| |
| public static void transferDefinitions(CompilationUnit from, CompilationUnit to) |
| { |
| to.topLevelDefinitions.addAll(from.topLevelDefinitions); |
| } |
| |
| public static void transferTypeInfo(CompilationUnit from, CompilationUnit to) |
| { |
| to.typeInfo = from.typeInfo; |
| } |
| |
| public static void clearDependencies(CompilationUnit unit) |
| { |
| unit.inheritance.clear(); |
| unit.types.clear(); |
| unit.expressions.clear(); |
| unit.namespaces.clear(); |
| unit.importPackageStatements.clear(); |
| unit.importDefinitionStatements.clear(); |
| } |
| |
| public static void transferInheritance(CompilationUnit from, CompilationUnit to) |
| { |
| to.inheritance.clear(); |
| to.inheritance.addAll(from.inheritance); |
| to.inheritanceHistory.putAll(from.inheritanceHistory); |
| } |
| |
| public static void transferDependencies(CompilationUnit from, CompilationUnit to) |
| { |
| clearDependencies(to); |
| |
| to.inheritance.addAll(from.inheritance); |
| to.types.addAll(from.types); |
| to.expressions.addAll(from.expressions); |
| to.namespaces.addAll(from.namespaces); |
| to.importPackageStatements.addAll(from.importPackageStatements); |
| to.importDefinitionStatements.addAll(from.importDefinitionStatements); |
| |
| to.inheritanceHistory.putAll(from.inheritanceHistory); |
| to.typeHistory.putAll(from.typeHistory); |
| to.expressionHistory.putAll(from.expressionHistory); |
| to.namespaceHistory.putAll(from.namespaceHistory); |
| } |
| |
| public static void transferNamespaces(CompilationUnit from, CompilationUnit to) |
| { |
| to.namespaces.clear(); |
| to.namespaces.addAll(from.namespaces); |
| to.namespaceHistory.putAll(from.namespaceHistory); |
| } |
| |
| public static void transferExpressions(CompilationUnit from, CompilationUnit to) |
| { |
| to.expressions.clear(); |
| to.expressions.addAll(from.expressions); |
| to.expressionHistory.putAll(from.expressionHistory); |
| } |
| |
| public static void transferAssets(CompilationUnit from, CompilationUnit to) |
| { |
| if (from.hasAssets()) |
| { |
| to.getAssets().addAll(from.getAssets()); |
| } |
| } |
| |
| public static void transferMetaData(CompilationUnit from, CompilationUnit to) |
| { |
| to.metadata.addAll(from.metadata); |
| to.swfMetaData = from.swfMetaData; |
| to.icon = from.icon; |
| to.iconFile = from.iconFile; |
| to.loaderClass = from.loaderClass; |
| to.extraClasses.addAll( from.extraClasses ); |
| to.addAccessibilityClasses(from); |
| to.licensedClassReqs.putAll( from.licensedClassReqs ); |
| to.remoteClassAliases.putAll(from.remoteClassAliases); |
| to.effectTriggers.putAll(from.effectTriggers); |
| to.mixins.addAll(from.mixins); |
| to.resourceBundles.addAll(from.resourceBundles); |
| to.resourceBundleHistory.addAll(from.resourceBundleHistory); |
| to.setSignatureChecksum(from.getSignatureChecksum()); |
| } |
| |
| public static void transferGeneratedSources(CompilationUnit from, CompilationUnit to) |
| { |
| to.addGeneratedSources(from.getGeneratedSources()); |
| from.clearGeneratedSources(); |
| } |
| |
| public static void transferClassTable(CompilationUnit from, CompilationUnit to) |
| { |
| to.classTable.putAll(from.classTable); |
| } |
| |
| public static void transferLoaderClassBase(CompilationUnit from, CompilationUnit to) |
| { |
| to.loaderClassBase = from.loaderClassBase; |
| } |
| |
| public static void transferBytecodes(CompilationUnit from, CompilationUnit to) |
| { |
| to.bytes.clear(); |
| to.bytes.set(from.bytes.toByteArray(false), from.bytes.size()); |
| to.getSource().lineCount = from.getSource().lineCount; |
| } |
| |
| public static void transferStyles(CompilationUnit from, CompilationUnit to) |
| { |
| to.styles = from.styles; |
| } |
| } |