Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.jangaroo.jooc.Jooc Maven / Gradle / Ivy
/*
* Copyright 2008 CoreMedia AG
*
* Licensed 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 net.jangaroo.jooc;
import net.jangaroo.jooc.api.CompilationResult;
import net.jangaroo.jooc.api.CompileLog;
import net.jangaroo.jooc.ast.CompilationUnit;
import net.jangaroo.jooc.ast.IdeDeclaration;
import net.jangaroo.jooc.ast.TransitiveAstVisitor;
import net.jangaroo.jooc.backend.CompilationUnitSink;
import net.jangaroo.jooc.backend.CompilationUnitSinkFactory;
import net.jangaroo.jooc.backend.JsCodeGenerator;
import net.jangaroo.jooc.backend.MergedOutputCompilationUnitSinkFactory;
import net.jangaroo.jooc.backend.SingleFileCompilationUnitSinkFactory;
import net.jangaroo.jooc.backend.TypeScriptCodeGenerator;
import net.jangaroo.jooc.backend.TypeScriptModuleResolver;
import net.jangaroo.jooc.cli.CommandLineParseException;
import net.jangaroo.jooc.cli.JoocCommandLineParser;
import net.jangaroo.jooc.config.JoocConfiguration;
import net.jangaroo.jooc.config.NamespaceConfiguration;
import net.jangaroo.jooc.config.PublicApiViolationsMode;
import net.jangaroo.jooc.input.FileInputSource;
import net.jangaroo.jooc.input.InputSource;
import net.jangaroo.jooc.input.PathInputSource;
import net.jangaroo.jooc.input.ZipEntryInputSource;
import net.jangaroo.jooc.mxml.CatalogComponentsParser;
import net.jangaroo.jooc.mxml.CatalogGenerator;
import net.jangaroo.jooc.mxml.ComponentPackageManifestParser;
import net.jangaroo.jooc.mxml.ComponentPackageModel;
import net.jangaroo.jooc.mxml.MxmlComponentRegistry;
import net.jangaroo.utils.CompilerUtils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* The Jangaroo AS3-to-JS Compiler's main class.
*
* @author Andreas Gawecki
* @author Frank Wienberg
*/
public class Jooc extends JangarooParser implements net.jangaroo.jooc.api.Jooc {
public static final String PUBLIC_API_EXCLUSION_ANNOTATION_NAME = "ExcludeClass";
public static final String PUBLIC_API_INCLUSION_ANNOTATION_NAME = "PublicApi";
public static final String DEPRECATED_ANNOTATION_NAME = "Deprecated";
public static final String NATIVE_ANNOTATION_NAME = "Native";
public static final String NATIVE_ANNOTATION_REQUIRE_PROPERTY = "require";
public static final String RENAME_ANNOTATION_NAME = "Rename";
public static final String MIXIN_ANNOTATION_NAME = "Mixin";
public static final String MIXIN_HOOK_ANNOTATION_NAME = "MixinHook";
public static final String MIXIN_HOOK_ANNOTATION_EXTENDED_ATTRIBUTE_NAME = "extended";
public static final String MIXIN_HOOK_ANNOTATION_DEFAULT_ATTRIBUTE_NAME = "on";
public static final Set MIXIN_HOOK_ANNOTATION_ATTRIBUTE_NAMES = new HashSet<>(Arrays.asList("before", "after",
MIXIN_HOOK_ANNOTATION_DEFAULT_ATTRIBUTE_NAME, MIXIN_HOOK_ANNOTATION_EXTENDED_ATTRIBUTE_NAME));
public static final String BINDABLE_ANNOTATION_NAME = "Bindable";
public static final String EXT_CONFIG_ANNOTATION_NAME = "ExtConfig";
public static final String EXT_PRIVATE_ANNOTATION_NAME = "ExtPrivate";
public static final String EMBED_ANNOTATION_NAME = "Embed";
public static final String EMBED_ANNOTATION_SOURCE_PROPERTY = "source";
public static final String EMBED_ANNOTATION_MIME_TYPE_PROPERTY = "mimeType";
public static final String EMBED_ANNOTATION_FONT_NAME_PROPERTY = "fontName";
public static final String RESOURCE_BUNDLE_ANNOTATION_NAME = "ResourceBundle";
public static final String ARRAY_ELEMENT_TYPE_ANNOTATION_NAME = "ArrayElementType";
public static final String EVENT_ANNOTATION_NAME = "Event";
public static final String EVENT_ANNOTATION_NAME_ATTRIBUTE_NAME = "name";
public static final String EVENT_ANNOTATION_TYPE_ATTRIBUTE_NAME = "type";
public static final String LAZY_ANNOTATION_NAME = "Lazy";
public static final String PARAMETER_ANNOTATION_NAME = "Parameter";
public static final String PARAMETER_ANNOTATION_REQUIRED_PROPERTY = "required";
public static final String PARAMETER_ANNOTATION_COERCE_TO_PROPERTY = "coerceTo";
public static final String COERCE_TO_VALUE_PROPERTIES_CLASS = "PropertiesClass";
public static final String COERCE_TO_VALUE_KEYOF_PREFIX = "keyof ";
public static final String RETURN_ANNOTATION_NAME = "Return";
public static final List ANNOTATIONS_FOR_COMPILER_ONLY = Arrays.asList(
Jooc.NATIVE_ANNOTATION_NAME,
Jooc.RENAME_ANNOTATION_NAME,
Jooc.EMBED_ANNOTATION_NAME,
Jooc.BINDABLE_ANNOTATION_NAME,
Jooc.ARRAY_ELEMENT_TYPE_ANNOTATION_NAME,
Jooc.EXT_CONFIG_ANNOTATION_NAME,
Jooc.RESOURCE_BUNDLE_ANNOTATION_NAME,
Jooc.MIXIN_ANNOTATION_NAME,
Jooc.MIXIN_HOOK_ANNOTATION_NAME,
Jooc.EXT_PRIVATE_ANNOTATION_NAME,
Jooc.PUBLIC_API_INCLUSION_ANNOTATION_NAME,
Jooc.PUBLIC_API_EXCLUSION_ANNOTATION_NAME,
Jooc.DEPRECATED_ANNOTATION_NAME,
Jooc.EVENT_ANNOTATION_NAME,
Jooc.LAZY_ANNOTATION_NAME,
Jooc.PARAMETER_ANNOTATION_NAME,
Jooc.RETURN_ANNOTATION_NAME
);
public static final String TS_SUFFIX = ".ts";
public static final String D_TS_SUFFIX = ".d" + TS_SUFFIX;
private final DependencyWarningsManager dependencyWarningsManager;
public static String getOutputSuffix(boolean isMigrateToTypeScript) {
return isMigrateToTypeScript ? TS_SUFFIX : OUTPUT_FILE_SUFFIX;
}
private final List compileQueue = new ArrayList<>();
public Jooc() {
this(new JoocConfiguration());
}
public Jooc(JoocConfiguration config) {
this(config, new StdOutCompileLog());
}
public Jooc(JoocConfiguration config, CompileLog log) {
super(config, log);
dependencyWarningsManager = new DependencyWarningsManager();
}
@Override
public JoocConfiguration getConfig() {
return (JoocConfiguration) super.getConfig();
}
@Override
public void setConfig(JoocConfiguration config) {
super.setConfig(config);
}
public String getOutputSuffix() {
return getOutputSuffix(getConfig().isMigrateToTypeScript());
}
@Override
public CompilationResult run() {
try {
return run1();
} catch (CompilerError e) {
logCompilerError(e);
return new CompilationResultImpl(CompilationResult.RESULT_CODE_COMPILATION_FAILED);
} catch (Exception e) {
e.printStackTrace(); // NOSONAR something serious happened and we cannot get it into the ordinary log
logCompilerError(e);
return new CompilationResultImpl(CompilationResult.RESULT_CODE_INTERNAL_COMPILER_ERROR);
}
}
private void logCompilerError(Throwable e) {
boolean causedBy = false;
for (Throwable current = e; current != null; current = current.getCause()) {
String message = current.getMessage();
if (causedBy) {
message = "Caused by: " + message;
}
if (current instanceof CompilerError && ((CompilerError) current).getSymbol() != null) {
log.error(((CompilerError) current).getSymbol(), message);
} else {
log.error(message);
}
causedBy = true;
}
}
private void findUnusedDependencies(CompilationUnit compilationUnit, InputSource classPathInputSource) {
dependencyWarningsManager.loadInputSource(classPathInputSource);
dependencyWarningsManager.updateUsedCompileDependencies(compilationUnit.getCompileDependencies().stream()
.map(this::findSource)
.map(InputSource::getPath)
.map(path -> path.split("!")[0])
.distinct()
.collect(Collectors.toList()));
}
private static final List IGNORE_DEPENDENCIES = Arrays.asList(
"Boolean.as",
"String.as",
"Number.as",
"Object.as",
"RegExp.as",
"int",
"uint",
"Date.as",
"Array.as",
"Error.as",
"Vector.as",
"Class.as",
"Function.as",
"XML.as"
);
private void checkUndeclaredDependencies(CompilationUnit compilationUnit) {
List usedUndeclaredDependencies = compilationUnit.getCompileDependencies().stream()
.map(this::findSource)
.filter(inputSource -> !IGNORE_DEPENDENCIES.contains(inputSource.getName()))
.filter(inputSource -> !(inputSource.isInSourcePath() || inputSource.isInCompilePath()))
.map(InputSource::getPath)
.filter(Objects::nonNull)
.distinct()
.filter(dependency -> !dependency.contains("jangaroo-runtime") && !dependency.contains("jangaroo-browser"))
.collect(Collectors.toList());
usedUndeclaredDependencies.forEach(dependency ->
dependencyWarningsManager.addDependencyWarning(dependency, compilationUnit.getInputSource().getName())
);
}
private CompilationResult run1() {
InputSource sourcePathInputSource;
InputSource classPathInputSource;
try {
String extNamespace = getConfig().getExtNamespace();
sourcePathInputSource = PathInputSource.fromFiles(getConfig().getSourcePath(), new String[]{""}, true, extNamespace);
classPathInputSource = PathInputSource.createCompilePathAwareClassPath(getConfig().getClassPath(), new String[]{"", JOO_API_IN_SWC_DIRECTORY_PREFIX}, extNamespace, getConfig().getCompilePath());
} catch (IOException e) {
throw new CompilerError("IO Exception occurred", e);
}
setUp(sourcePathInputSource, classPathInputSource);
HashMap outputFileMap = new HashMap<>();
try {
setUpMxmlComponentRegistry(sourcePathInputSource, classPathInputSource);
for (File sourceFile : getConfig().getSourceFiles()) {
processSource(sourceFile);
}
CompilationUnitSinkFactory codeSinkFactory = createSinkFactory(getConfig(), null);
CompilationUnitSinkFactory dTsSinkFactory = createSinkFactory(getConfig(), D_TS_SUFFIX);
CompilationUnitSinkFactory apiSinkFactory = createSinkFactory(getConfig(), AS_SUFFIX);
ImplementedMembersAnalyzer implementedMembersAnalyzer = new ImplementedMembersAnalyzer(this);
for (InputSource inputSource : compileQueue) {
CompilationUnit unit = importSource(inputSource);
if (unit != null) {
checkValidFileName(unit);
unit.analyze(null);
if (getConfig().isFindUnusedDependencies()) {
findUnusedDependencies(unit, classPathInputSource);
}
checkUndeclaredDependencies(unit);
if (getConfig().getPublicApiViolationsMode() != PublicApiViolationsMode.ALLOW) {
reportPublicApiViolations(unit);
}
implementedMembersAnalyzer.analyzeImplementedMembers(unit);
TypeChecker typeChecker = new TypeChecker(log);
unit.visit(new TransitiveAstVisitor(typeChecker));
}
}
if (!dependencyWarningsManager.getDependencyWarnings().isEmpty()) {
List lines = new ArrayList<>();
dependencyWarningsManager.getDependencyWarnings()
.forEach(dependencyWarning -> {
lines.add(String.format("Undeclared dependency %s was used by:", Paths.get(dependencyWarning.getDependency()).getFileName()));
dependencyWarning.getUsages().forEach(s -> lines.add(" " + s));
});
getLog().warning(String.join("\n", lines));
}
for (InputSource source : compileQueue) {
File sourceFile = ((FileInputSource) source).getFile();
File outputFile = null;
try {
String sourceName = source.getName();
boolean isPropertiesSource = sourceName.endsWith(PROPERTIES_SUFFIX);
CompilationUnit unit = importSource(source);
if (unit != null) {
final IdeDeclaration primaryDeclaration = unit.getPrimaryDeclaration();
CompilationUnitSinkFactory currentCodeSinkFactory = codeSinkFactory;
boolean generatesCode;
if (!getConfig().isMigrateToTypeScript()) {
generatesCode = JsCodeGenerator.generatesCode(primaryDeclaration);
} else {
generatesCode = TypeScriptCodeGenerator.generatesCode(primaryDeclaration);
if (generatesCode && TypeScriptModuleResolver.getNonRequireNativeName(primaryDeclaration) != null) {
currentCodeSinkFactory = dTsSinkFactory;
}
}
if (generatesCode) {
outputFile = writeOutput(sourceFile, unit, currentCodeSinkFactory, getConfig().isVerbose());
}
if (getConfig().isGenerateApi()) {
writeOutput(sourceFile, unit, apiSinkFactory, getConfig().isVerbose());
if (isPropertiesSource && isDefaultLocale(sourceName)) {
// copy default locale properties to joo-api so Idea can find them
File apiOutputDirectory = getConfig().getApiOutputDirectory();
String relativeSourcePath = source.getRelativePath();
File apiFile = new File(apiOutputDirectory, relativeSourcePath);
Files.copy(sourceFile.toPath(), apiFile.toPath(),
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
}
}
}
} catch (IOException e) {
getLog().error(fileToSymbol(sourceFile), e.getClass().getName() + ": " + e.getMessage());
}
outputFileMap.put(sourceFile, outputFile); // always map source file, even if output file is null!
}
compileQueue.clear();
copySassFiles();
if (getConfig().getDependencyReportOutputFile() != null) {
File dependencyWarningsFile = new File(getConfig().getDependencyReportOutputFile());
if (!dependencyWarningsFile.getParentFile().exists()) {
dependencyWarningsFile.getParentFile().mkdirs();
}
if (!dependencyWarningsFile.exists()) {
dependencyWarningsFile.createNewFile();
}
try (FileWriter fileWriter = new FileWriter(dependencyWarningsFile)) {
fileWriter.write(dependencyWarningsManager.createFileString());
}
}
int result = log.hasErrors() ? CompilationResult.RESULT_CODE_COMPILATION_FAILED : CompilationResult.RESULT_CODE_OK;
return new CompilationResultImpl(result, outputFileMap);
} catch (IOException e) {
throw new CompilerError(e.getClass().getName() + ": " + e.getMessage(), e);
} finally {
tearDown();
}
}
private boolean isDefaultLocale(String sourceName) {
return sourceName.indexOf('_') < 0;
}
private void checkValidFileName(final CompilationUnit unit) {
InputSource source = getInputSource(unit);
if (!source.getName().endsWith(AS_SUFFIX)) {
// Only check *.as file names.
// For *.properties and *.mxml, the class name is derived from the file name, anyway!
return;
}
// check valid file name for qname
String path = source.getRelativePath();
if (path != null) {
String qname = unit.getPrimaryDeclaration().getQualifiedNameStr();
String expectedPath = CompilerUtils.fileNameFromQName(qname, File.separatorChar, AS_SUFFIX);
if (!expectedPath.equals(path)) {
warning(unit.getSymbol(),
String.format("expected '%s' as the file name for %s, found: '%s'. -sourcepath not set (correctly)?",
expectedPath,
qname,
path));
}
}
}
private void setUpMxmlComponentRegistry(InputSource sourcePathInputSource, InputSource classPathInputSource)
throws IOException {
// scan classpath for catalog.xml-s:
List children = classPathInputSource.getChildren("catalog.xml");
CatalogComponentsParser catalogParser =
new CatalogComponentsParser(getMxmlComponentRegistry());
for (InputSource child : children) {
catalogParser.parse(child.getInputStream());
}
// find manifest.xml for this module's component definitions:
MxmlComponentRegistry localMxmlComponentRegistry = new MxmlComponentRegistry();
List namespaces = getConfig().getNamespaces();
for (NamespaceConfiguration namespace : namespaces) {
File componentPackageManifest = namespace.getManifest();
InputSource componentPackageManifestInputSource;
if (componentPackageManifest == null) {
// look for default manifest file:
componentPackageManifestInputSource = sourcePathInputSource.getChild("manifest.xml");
} else {
componentPackageManifestInputSource = new FileInputSource(componentPackageManifest, false);
}
if (componentPackageManifestInputSource != null) {
InputStream manifestInputStream = componentPackageManifestInputSource.getInputStream();
ComponentPackageModel componentPackageModel =
new ComponentPackageManifestParser(namespace.getUri()).parse(manifestInputStream);
getMxmlComponentRegistry().add(componentPackageModel);
localMxmlComponentRegistry.add(componentPackageModel);
}
}
File catalogOutputDirectory = getConfig().getCatalogOutputDirectory();
if (catalogOutputDirectory != null && !localMxmlComponentRegistry.getComponentPackageModels().isEmpty()) {
//noinspection ResultOfMethodCallIgnored
catalogOutputDirectory.mkdirs();
new CatalogGenerator(localMxmlComponentRegistry).generateCatalog(new File(catalogOutputDirectory, "catalog.xml"));
}
}
private void reportPublicApiViolations(CompilationUnit unit) {
Set dependenciesForPublicAPICheck = new HashSet<>(unit.getCompileDependencies());
for (String qName : dependenciesForPublicAPICheck) {
CompilationUnit compilationUnit = getCompilationUnit(qName);
if (getInputSource(compilationUnit) instanceof ZipEntryInputSource
&& compilationUnit.getPackageDeclaration().getAnnotation(PUBLIC_API_EXCLUSION_ANNOTATION_NAME) != null) {
String msg = "PUBLIC API VIOLATION: " + compilationUnit.getPrimaryDeclaration().getQualifiedNameStr();
File sourceFile = new File(unit.getSymbol().getFileName());
if (getConfig().getPublicApiViolationsMode() == PublicApiViolationsMode.WARN) {
JangarooParser.warning(msg, sourceFile);
} else {
throw JangarooParser.error(msg, sourceFile);
}
}
}
}
public File writeOutput(File sourceFile,
CompilationUnit compilationUnit,
CompilationUnitSinkFactory writerFactory,
boolean verbose) throws CompilerError {
CompilationUnitSink sink = writerFactory.createSink(
compilationUnit.getPackageDeclaration(), compilationUnit.getPrimaryDeclaration(),
sourceFile, verbose);
return sink.writeOutput(compilationUnit);
}
private CompilationUnitSinkFactory createSinkFactory(JoocConfiguration config, String suffix) {
CompilationUnitSinkFactory codeSinkFactory = null;
if (suffix == null) {
suffix = getOutputSuffix();
}
boolean generateTypeScriptIndexDTS = D_TS_SUFFIX.equals(suffix);
boolean generateActionScriptApi = AS_SUFFIX.equals(suffix);
if (OUTPUT_FILE_SUFFIX.equals(suffix) && config.isMergeOutput()
|| generateTypeScriptIndexDTS && config.isMigrateToTypeScript()) {
File outputFile = config.isMergeOutput() ? config.getOutputFile()
: new File(getConfig().getOutputDirectory(), "index" + D_TS_SUFFIX);
codeSinkFactory = new MergedOutputCompilationUnitSinkFactory(config, outputFile, this, this);
} else if (!(generateActionScriptApi && !config.isGenerateApi()) && !generateTypeScriptIndexDTS) {
File outputDirectory = generateActionScriptApi ? config.getApiOutputDirectory() : config.getOutputDirectory();
final String nativeSuffix = !generateActionScriptApi && config.isMigrateToTypeScript() ? D_TS_SUFFIX : null;
codeSinkFactory = new SingleFileCompilationUnitSinkFactory(config, outputDirectory, generateActionScriptApi, suffix, nativeSuffix, this, this);
}
return codeSinkFactory;
}
public static String getResultCodeDescription(int resultCode) {
switch (resultCode) {
case CompilationResult.RESULT_CODE_OK:
return "ok";
case CompilationResult.RESULT_CODE_COMPILATION_FAILED:
return "compilation failed";
case CompilationResult.RESULT_CODE_INTERNAL_COMPILER_ERROR:
return "internal compiler error";
case CompilationResult.RESULT_CODE_UNRECOGNIZED_OPTION:
return "unrecognized option";
case CompilationResult.RESULT_CODE_MISSING_OPTION_ARGUMENT:
return "missing option argument";
case CompilationResult.RESULT_CODE_ILLEGAL_OPTION_VALUE:
return "illegal option value";
default:
return "unknown result code";
}
}
protected void processSource(File file) throws IOException {
if (file.isDirectory()) {
throw error("Input file is a directory.", file);
}
File sourceDir = getConfig().findSourceDir(file);
// String qName = CompilerUtils.qNameFromFile(sourceDir, file);
// InputSource canonicalInputSource = findSource(qName);
// if (canonicalInputSource != null && !canonicalInputSource.getPath().equals(file.getPath())) {
// if (canonicalInputSource.getName().endsWith(PROPERTIES_SUFFIX)) {
// // ignore classes generated from properties files!
// return;
// }
// throw Jooc.error(String.format("Compilation unit %s defined in %s is redeclared in %s.", qName, canonicalInputSource.getPath(), file.getPath()), file);
// }
FileInputSource inputSource = new FileInputSource(sourceDir, file, true, getConfig().getExtNamespace());
compileQueue.add(inputSource);
importSource(inputSource);
}
protected void copySassFiles() throws IOException {
String extSassNamespace = getConfig().getExtSassNamespace();
for (String sassSourceSubFolderName : getConfig().getSassSourceFilesByType().keySet()) {
File sassSourceSubFolder = getConfig().getSassSourcePathByType().get(sassSourceSubFolderName);
File sassTargetSubFolder = getConfig().getSassOutputDirectoryByType().get(sassSourceSubFolderName);
if (sassSourceSubFolder == null) {
getLog().error("No sass source folder registered for folder type: " + sassSourceSubFolderName);
continue;
}
if (sassTargetSubFolder == null) {
getLog().error("No sass output folder registered for folder type: " + sassSourceSubFolderName);
continue;
}
for (File sassSourceFile : getConfig().getSassSourceFilesByType().get(sassSourceSubFolderName)) {
File sassTargetFile;
Path relativeSrcPath = sassSourceSubFolder.toPath().relativize(sassSourceFile.toPath());
String srcFileName = sassSourceFile.getName();
if (!srcFileName.endsWith(SCSS_SUFFIX)) {
getLog().warning("Cannot handle unknown extension in sass directory for file: " + sassSourceFile);
sassTargetFile = sassTargetSubFolder.toPath().resolve(relativeSrcPath).toFile();
} else {
String fqn = CompilerUtils.qNameFromFile(sassSourceSubFolder, sassSourceFile);
// apply possible renaming
CompilationUnit compilationUnit = getCompilationUnit(fqn);
String newFqn;
if (compilationUnit != null) {
newFqn = compilationUnit.getPrimaryDeclaration().getTargetQualifiedNameStr();
} else {
// do not rename
newFqn = fqn;
getLog().warning(String.format("Could not find compilation unit %s for SASS file %s", fqn, srcFileName));
}
// apply extSassNamespace
if (!extSassNamespace.isEmpty()) {
if (!newFqn.startsWith(extSassNamespace) || extSassNamespace.equals(newFqn)) {
getLog().error(String.format("Invalid extSassNamespace configuration %s! The following file location would be transformed: %s", extSassNamespace, sassSourceFile));
continue;
}
newFqn = newFqn.substring(extSassNamespace.length() + 1);
}
sassTargetFile = CompilerUtils.fileFromQName(newFqn, sassTargetSubFolder, SCSS_SUFFIX);
}
//noinspection ResultOfMethodCallIgnored
sassTargetFile.getParentFile().mkdirs();
try {
Files.copy(sassSourceFile.toPath(),
sassTargetFile.toPath(),
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES,
LinkOption.NOFOLLOW_LINKS);
} catch (IOException e) {
getLog().error(String.format("Could not copy file %s to %s", sassSourceFile, sassTargetFile));
}
}
}
}
public static int run(String[] argv, CompileLog log) {
try {
JoocCommandLineParser commandLineParser = new JoocCommandLineParser();
JoocConfiguration config = commandLineParser.parse(argv);
if (config != null) {
return new Jooc(config, log).run().getResultCode();
}
} catch (CommandLineParseException e) {
System.out.println(e.getMessage()); // NOSONAR this is a commandline tool
return e.getExitCode();
}
return CompilationResult.RESULT_CODE_OK;
}
public static void main(String[] argv) {
int result = run(argv, new StdOutCompileLog());
if (result != 0) {
System.exit(result);
}
}
}