/* * * 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.units; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import org.apache.commons.io.IOUtils; import org.apache.flex.compiler.problems.ICompilerProblem; import org.apache.flex.compiler.problems.InternalCompilerProblem2; import org.apache.flex.compiler.problems.InvalidABCByteCodeProblem; import org.apache.flex.compiler.problems.NoScopesInABCCompilationUnitProblem; import org.apache.flex.compiler.filespecs.IBinaryFileSpecification; import org.apache.flex.compiler.filespecs.IFileSpecification; import org.apache.flex.compiler.internal.abc.ABCScopeBuilder; import org.apache.flex.compiler.internal.projects.CompilerProject; import org.apache.flex.compiler.internal.projects.DefinitionPriority; import org.apache.flex.compiler.internal.scopes.ASFileScopeProvider; import org.apache.flex.compiler.internal.units.requests.ABCBytesRequestResult; import org.apache.flex.compiler.internal.units.requests.ABCFileScopeRequestResult; import org.apache.flex.compiler.internal.units.requests.SyntaxTreeRequestResult; import org.apache.flex.compiler.scopes.IASScope; import org.apache.flex.compiler.units.ICompilationUnit; import org.apache.flex.compiler.units.requests.IABCBytesRequestResult; import org.apache.flex.compiler.units.requests.IFileScopeRequestResult; import org.apache.flex.compiler.units.requests.IOutgoingDependenciesRequestResult; import org.apache.flex.compiler.units.requests.ISWFTagsRequestResult; import org.apache.flex.compiler.units.requests.ISyntaxTreeRequestResult; import org.apache.flex.swf.SWFFrame; import org.apache.flex.swf.tags.DoABCTag; /** * This class represents a compilation unit for an ABC file. */ public class ABCCompilationUnit extends CompilationUnitBase { /** * Create a compilation unit from an ABC file. * * @param project compiler project * @param path ABC file path */ public ABCCompilationUnit(CompilerProject project, String path) { super(project, path, DefinitionPriority.BasePriority.LIBRARY_PATH, false); } private static final String SUB_SYSTEM = "ABCCompilationUnit"; // Used for error reporting @Override public UnitType getCompilationUnitType() { return UnitType.ABC_UNIT; } public Operation[] notifyDependencyOperationResultsInvalid(ICompilationUnit dependency, Operation[] invalidatedOperations) { // TODO Auto-generated method stub return null; } @Override protected ISyntaxTreeRequestResult handleSyntaxTreeRequest() throws InterruptedException { startProfile(Operation.GET_SYNTAX_TREE); try { List<ICompilerProblem> noProblems = Collections.emptyList(); return new SyntaxTreeRequestResult(getRootFileSpecification().getLastModified(), noProblems); } finally { stopProfile(Operation.GET_SYNTAX_TREE); } } @Override protected IFileScopeRequestResult handleFileScopeRequest() throws InterruptedException { startProfile(Operation.GET_FILESCOPE); getProject().clearScopeCacheForCompilationUnit(this); // we should always have a binary file spec when dealing with ABC compilation units final Collection<ICompilerProblem> problems = new HashSet<ICompilerProblem>(); byte[] abcData = getABCBytes(problems); List<IASScope> scopeList = null; try { final String path = getAbsoluteFilename(); final ABCScopeBuilder abcScopeBuilder = new ABCScopeBuilder( this.getProject().getWorkspace(), abcData, path, ASFileScopeProvider.getInstance()); scopeList = abcScopeBuilder.build(); if (scopeList.isEmpty()) { final NoScopesInABCCompilationUnitProblem problem = new NoScopesInABCCompilationUnitProblem(path); problems.add(problem); } } catch (Exception e) { final InvalidABCByteCodeProblem problem = new InvalidABCByteCodeProblem(getRootFileSpecification().getPath()); problems.add(problem); } final ABCFileScopeRequestResult result = new ABCFileScopeRequestResult(problems, scopeList); stopProfile(Operation.GET_FILESCOPE); return result; } @Override protected IABCBytesRequestResult handleABCBytesRequest() throws InterruptedException { startProfile(Operation.GET_ABC_BYTES); IABCBytesRequestResult result = new ABCBytesRequestResult(); stopProfile(Operation.GET_ABC_BYTES); return result; } @Override protected ISWFTagsRequestResult handleSWFTagsRequest() throws InterruptedException { startProfile(Operation.GET_SWF_TAGS); ISWFTagsRequestResult result = new ISWFTagsRequestResult() { @Override public boolean addToFrame(SWFFrame frame) { // TODO add ABC compilation unit to SWF return true; } @Override public ICompilerProblem[] getProblems() { return IABCBytesRequestResult.ZEROPROBLEMS; } @Override public String getDoABCTagName() { return ""; } @Override public DoABCTag getDoABCTag() { return null; } }; stopProfile(Operation.GET_SWF_TAGS); return result; } @Override protected IOutgoingDependenciesRequestResult handleOutgoingDependenciesRequest () throws InterruptedException { startProfile(Operation.GET_SEMANTIC_PROBLEMS); IOutgoingDependenciesRequestResult result = new IOutgoingDependenciesRequestResult() { @Override public ICompilerProblem[] getProblems() { return IABCBytesRequestResult.ZEROPROBLEMS; } }; stopProfile(Operation.GET_SEMANTIC_PROBLEMS); return result; } protected byte[] getABCBytes(Collection<ICompilerProblem> problems) { IFileSpecification rootSource = getRootFileSpecification(); byte[] abcData = null; if (rootSource instanceof IBinaryFileSpecification) { IBinaryFileSpecification abcFileSpec = (IBinaryFileSpecification)rootSource; InputStream abcStream = null; try { abcStream = abcFileSpec.createInputStream(); abcData = IOUtils.toByteArray(abcStream); assert abcData != null : "No ABC byte code."; } catch (Exception e) { final ICompilerProblem problem = new InternalCompilerProblem2(rootSource.getPath(), e, SUB_SYSTEM); problems.add(problem); } finally { if (abcStream != null) { try { abcStream.close(); } catch (IOException e) { final ICompilerProblem problem = new InternalCompilerProblem2(rootSource.getPath(), e, SUB_SYSTEM); problems.add(problem); } } } } else { final InvalidABCByteCodeProblem problem = new InvalidABCByteCodeProblem(rootSource.getPath()); problems.add(problem); } return abcData; } }