| /* |
| * |
| * 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.test; |
| |
| import static org.hamcrest.core.Is.is; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertThat; |
| |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.OutputStreamWriter; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import org.apache.flex.compiler.codegen.as.IASEmitter; |
| import org.apache.flex.compiler.codegen.mxml.IMXMLEmitter; |
| import org.apache.flex.compiler.config.Configurator; |
| import org.apache.flex.compiler.driver.IBackend; |
| import org.apache.flex.compiler.internal.codegen.as.ASFilterWriter; |
| import org.apache.flex.compiler.internal.projects.FlexJSProject; |
| import org.apache.flex.compiler.internal.projects.FlexProject; |
| import org.apache.flex.compiler.internal.projects.FlexProjectConfigurator; |
| import org.apache.flex.compiler.internal.projects.ISourceFileHandler; |
| import org.apache.flex.compiler.internal.targets.JSTarget; |
| import org.apache.flex.compiler.internal.tree.as.FunctionNode; |
| import org.apache.flex.compiler.internal.tree.as.ImportNode; |
| import org.apache.flex.compiler.internal.workspaces.Workspace; |
| import org.apache.flex.compiler.mxml.IMXMLNamespaceMapping; |
| import org.apache.flex.compiler.problems.ICompilerProblem; |
| import org.apache.flex.compiler.projects.ICompilerProject; |
| import org.apache.flex.compiler.tree.as.IASNode; |
| import org.apache.flex.compiler.tree.as.IFileNode; |
| import org.apache.flex.compiler.tree.mxml.IMXMLFileNode; |
| import org.apache.flex.compiler.units.ICompilationUnit; |
| import org.apache.flex.compiler.utils.EnvProperties; |
| import org.apache.flex.compiler.visitor.as.IASBlockWalker; |
| import org.apache.flex.compiler.visitor.mxml.IMXMLBlockWalker; |
| import org.apache.flex.utils.FilenameNormalization; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Ignore; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| |
| @Ignore |
| public class TestBase implements ITestBase |
| { |
| protected List<ICompilerProblem> errors; |
| |
| protected static EnvProperties env = EnvProperties.initiate(); |
| |
| protected static Workspace workspace = new Workspace(); |
| protected FlexProject project; |
| |
| protected IBackend backend; |
| protected ASFilterWriter writer; |
| |
| protected IASEmitter asEmitter; |
| protected IMXMLEmitter mxmlEmitter; |
| |
| protected IASBlockWalker asBlockWalker; |
| protected IMXMLBlockWalker mxmlBlockWalker; |
| |
| protected String inputFileExtension; |
| |
| protected String mCode; |
| |
| protected File tempDir; |
| |
| private List<File> sourcePaths = new ArrayList<File>(); |
| private List<File> libraries = new ArrayList<File>(); |
| private List<IMXMLNamespaceMapping> namespaceMappings = new ArrayList<IMXMLNamespaceMapping>(); |
| |
| @Before |
| public void setUp() |
| { |
| assertNotNull("Environment variable FLEX_HOME is not set", env.SDK); |
| assertNotNull("Environment variable PLAYERGLOBAL_HOME is not set", |
| env.FPSDK); |
| |
| errors = new ArrayList<ICompilerProblem>(); |
| |
| if (project == null) |
| project = new FlexProject(workspace); |
| FlexProjectConfigurator.configure(project); |
| |
| backend = createBackend(); |
| writer = backend.createWriterBuffer(project); |
| |
| try |
| { |
| ISourceFileHandler sfh = backend.getSourceFileHandlerInstance(); |
| inputFileExtension = "." + sfh.getExtensions()[0]; |
| } |
| catch (Exception e) |
| { |
| inputFileExtension = ".as"; |
| } |
| |
| sourcePaths = new ArrayList<File>(); |
| libraries = new ArrayList<File>(); |
| namespaceMappings = new ArrayList<IMXMLNamespaceMapping>(); |
| |
| tempDir = new File(FilenameNormalization.normalize("temp")); // ensure this exists |
| } |
| |
| @After |
| public void tearDown() |
| { |
| backend = null; |
| writer = null; |
| } |
| |
| protected IBackend createBackend() |
| { |
| return null; |
| } |
| |
| protected void assertOut(String code) |
| { |
| mCode = writer.toString(); |
| //System.out.println(mCode); |
| assertThat(mCode, is(code)); |
| } |
| |
| @Override |
| public String toString() |
| { |
| return writer.toString(); |
| } |
| |
| protected IFileNode compileAS(String input) |
| { |
| return compileAS(input, false, ""); |
| } |
| |
| protected IFileNode compileAS(String input, boolean isFileName, |
| String inputDir) |
| { |
| return compileAS(input, isFileName, inputDir, true); |
| } |
| |
| protected IFileNode compileAS(String input, boolean isFileName, |
| String inputDir, boolean useTempFile) |
| { |
| return (IFileNode) compile(input, isFileName, inputDir, useTempFile); |
| } |
| |
| protected IASNode compile(String input, boolean isFileName, |
| String inputDir, boolean useTempFile) |
| { |
| File tempFile = (useTempFile) ? writeCodeToTempFile(input, isFileName, |
| inputDir) : new File(FilenameNormalization.normalize(inputDir |
| + File.separator + input + inputFileExtension)); |
| |
| addDependencies(); |
| |
| String normalizedMainFileName = FilenameNormalization |
| .normalize(tempFile.getAbsolutePath()); |
| |
| Collection<ICompilationUnit> mainFileCompilationUnits = workspace |
| .getCompilationUnits(normalizedMainFileName, project); |
| |
| ICompilationUnit cu = null; |
| for (ICompilationUnit cu2 : mainFileCompilationUnits) |
| { |
| if (cu2 != null) |
| cu = cu2; |
| } |
| |
| IASNode fileNode = null; |
| try |
| { |
| fileNode = cu.getSyntaxTreeRequest().get().getAST(); |
| } |
| catch (InterruptedException e) |
| { |
| e.printStackTrace(); |
| } |
| |
| return fileNode; |
| } |
| |
| protected List<String> compileProject(String inputFileName, |
| String inputDirName) |
| { |
| List<String> compiledFileNames = new ArrayList<String>(); |
| |
| String mainFileName = "test-files" |
| + File.separator + inputDirName + File.separator |
| + inputFileName + inputFileExtension; |
| |
| addDependencies(); |
| |
| ICompilationUnit mainCU = Iterables |
| .getOnlyElement(workspace.getCompilationUnits( |
| FilenameNormalization.normalize(mainFileName), project)); |
| |
| if (project instanceof FlexJSProject) |
| ((FlexJSProject) project).mainCU = mainCU; |
| |
| Configurator projectConfigurator = backend.createConfigurator(); |
| |
| JSTarget target = (JSTarget) backend.createTarget(project, |
| projectConfigurator.getTargetSettings(null), null); |
| |
| target.build(mainCU, new ArrayList<ICompilerProblem>()); |
| |
| List<ICompilationUnit> reachableCompilationUnits = project |
| .getReachableCompilationUnitsInSWFOrder(ImmutableSet.of(mainCU)); |
| for (final ICompilationUnit cu : reachableCompilationUnits) |
| { |
| try |
| { |
| ICompilationUnit.UnitType cuType = cu.getCompilationUnitType(); |
| |
| if (cuType == ICompilationUnit.UnitType.AS_UNIT |
| || cuType == ICompilationUnit.UnitType.MXML_UNIT) |
| { |
| File outputRootDir = new File( |
| FilenameNormalization.normalize(tempDir |
| + File.separator + inputDirName)); |
| |
| String qname = cu.getQualifiedNames().get(0); |
| |
| compiledFileNames.add(qname.replace(".", "/")); |
| |
| final File outputClassFile = getOutputClassFile(qname |
| + "_output", outputRootDir); |
| |
| ASFilterWriter writer = backend.createWriterBuffer(project); |
| IASEmitter emitter = backend.createEmitter(writer); |
| IASBlockWalker walker = backend.createWalker(project, |
| errors, emitter); |
| |
| walker.visitCompilationUnit(cu); |
| |
| //System.out.println(writer.toString()); |
| |
| BufferedOutputStream out = new BufferedOutputStream( |
| new FileOutputStream(outputClassFile)); |
| |
| out.write(writer.toString().getBytes()); |
| out.flush(); |
| out.close(); |
| } |
| } |
| catch (Exception e) |
| { |
| //System.out.println(e.getMessage()); |
| } |
| } |
| |
| return compiledFileNames; |
| } |
| |
| protected File getOutputClassFile(String qname, File outputFolder) |
| { |
| String[] cname = qname.split("\\."); |
| String sdirPath = outputFolder + File.separator; |
| if (cname.length > 0) |
| { |
| for (int i = 0, n = cname.length - 1; i < n; i++) |
| { |
| sdirPath += cname[i] + File.separator; |
| } |
| |
| File sdir = new File(sdirPath); |
| if (!sdir.exists()) |
| sdir.mkdirs(); |
| |
| qname = cname[cname.length - 1]; |
| } |
| |
| return new File(sdirPath + qname + "." + backend.getOutputExtension()); |
| } |
| |
| protected IMXMLFileNode compileMXML(String input) |
| { |
| return compileMXML(input, false, ""); |
| } |
| |
| protected IMXMLFileNode compileMXML(String input, boolean isFileName, |
| String inputDir) |
| { |
| return compileMXML(input, isFileName, inputDir, true); |
| } |
| |
| protected IMXMLFileNode compileMXML(String input, boolean isFileName, |
| String inputDir, boolean useTempFile) |
| { |
| return (IMXMLFileNode) compile(input, isFileName, inputDir, useTempFile); |
| } |
| |
| protected File writeCodeToTempFile(String input, boolean isFileName, |
| String inputDir) |
| { |
| File tempASFile = null; |
| try |
| { |
| String tempFileName = (isFileName) ? input : getClass() |
| .getSimpleName(); |
| |
| tempASFile = File.createTempFile(tempFileName, inputFileExtension, |
| tempDir); |
| tempASFile.deleteOnExit(); |
| |
| String code = ""; |
| if (!isFileName) |
| { |
| code = input; |
| } |
| else |
| { |
| code = getCodeFromFile(input, false, inputDir); |
| } |
| |
| BufferedWriter out = new BufferedWriter(new FileWriter(tempASFile)); |
| out.write(code); |
| out.close(); |
| } |
| catch (IOException e1) |
| { |
| e1.printStackTrace(); |
| } |
| |
| return tempASFile; |
| } |
| |
| protected void writeResultToFile(String result, String fileName) |
| { |
| BufferedWriter writer = null; |
| try |
| { |
| writer = new BufferedWriter(new OutputStreamWriter( |
| new FileOutputStream(new File(tempDir, fileName + ".js")), |
| "utf-8")); |
| writer.write(result); |
| } |
| catch (IOException e1) |
| { |
| e1.printStackTrace(); |
| } |
| finally |
| { |
| try |
| { |
| writer.close(); |
| } |
| catch (Exception ex) |
| { |
| } |
| } |
| } |
| |
| /** |
| * Overridable setup of dependencies, default adds source, libraries and |
| * namepsaces. |
| * <p> |
| * The test will then set the dependencies on the current |
| * {@link ICompilerProject}. |
| */ |
| protected void addDependencies() |
| { |
| addSourcePaths(sourcePaths); |
| addLibraries(libraries); |
| addNamespaceMappings(namespaceMappings); |
| |
| project.setSourcePath(sourcePaths); |
| project.setLibraries(libraries); |
| project.setNamespaceMappings(namespaceMappings); |
| } |
| |
| protected void addLibraries(List<File> libraries) |
| { |
| } |
| |
| protected void addSourcePaths(List<File> sourcePaths) |
| { |
| sourcePaths.add(tempDir); |
| } |
| |
| protected void addNamespaceMappings( |
| List<IMXMLNamespaceMapping> namespaceMappings) |
| { |
| } |
| |
| protected String getCodeFromFile(String fileName, boolean isJS, |
| String sourceDir) |
| { |
| String testFileDir = FilenameNormalization.normalize("test-files"); |
| |
| File testFile = new File(testFileDir |
| + File.separator + sourceDir + File.separator + fileName |
| + (isJS ? ".js" : inputFileExtension)); |
| |
| return readCodeFile(testFile); |
| } |
| |
| protected String readCodeFile(File file) |
| { |
| boolean isResult = file.getName().contains("_result") || file.getName().equals("output.js"); |
| String code = ""; |
| try |
| { |
| BufferedReader in = new BufferedReader(new InputStreamReader( |
| new FileInputStream(file), "UTF8")); |
| |
| String line = in.readLine(); |
| if (line.contains("/**") && isResult) |
| { |
| // eat opening comment which should be apache header |
| while (line != null) |
| { |
| line = in.readLine(); |
| if (line.contains("*/")) |
| { |
| line = in.readLine(); |
| break; |
| } |
| } |
| } |
| while (line != null) |
| { |
| code += line + "\n"; |
| line = in.readLine(); |
| } |
| code = code.substring(0, code.length() - 1); |
| |
| in.close(); |
| } |
| catch (Exception e) |
| { |
| } |
| return code; |
| } |
| |
| protected IASNode findFirstDescendantOfType(IASNode node, |
| Class<? extends IASNode> nodeType) |
| { |
| int n = node.getChildCount(); |
| for (int i = 0; i < n; i++) |
| { |
| IASNode child = node.getChild(i); |
| if (child instanceof ImportNode) |
| continue; // not interested in these and they have BinaryOps inside |
| if (child instanceof FunctionNode) |
| { |
| ((FunctionNode) child).parseFunctionBody(errors); |
| } |
| if (nodeType.isInstance(child)) |
| return child; |
| |
| IASNode found = findFirstDescendantOfType(child, nodeType); |
| if (found != null) |
| return found; |
| } |
| |
| return null; |
| } |
| |
| } |