com.redhat.ceylon.compiler.java.tools.CeyloncFileManager Maven / Gradle / Ivy
/*
* Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Copyright Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the authors tag. All rights reserved.
*
*/
package com.redhat.ceylon.compiler.java.tools;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.redhat.ceylon.common.log.Logger;
import com.redhat.ceylon.cmr.api.Overrides;
import com.redhat.ceylon.cmr.api.RepositoryManager;
import com.redhat.ceylon.cmr.ceylon.CeylonUtils;
import com.redhat.ceylon.cmr.impl.CachingRepositoryManager;
import com.redhat.ceylon.common.FileUtil;
import com.redhat.ceylon.common.config.Repositories;
import com.redhat.ceylon.compiler.java.codegen.CeylonFileObject;
import com.redhat.ceylon.compiler.java.util.Util;
import com.redhat.ceylon.javax.tools.FileObject;
import com.redhat.ceylon.javax.tools.JavaFileManager;
import com.redhat.ceylon.javax.tools.JavaFileObject;
import com.redhat.ceylon.javax.tools.StandardJavaFileManager;
import com.redhat.ceylon.javax.tools.StandardLocation;
import com.redhat.ceylon.javax.tools.JavaFileObject.Kind;
import com.redhat.ceylon.langtools.source.util.TaskListener;
import com.redhat.ceylon.langtools.tools.javac.file.JavacFileManager;
import com.redhat.ceylon.langtools.tools.javac.file.RegularFileObject;
import com.redhat.ceylon.langtools.tools.javac.file.RelativePath.RelativeFile;
import com.redhat.ceylon.langtools.tools.javac.main.OptionName;
import com.redhat.ceylon.langtools.tools.javac.util.Context;
import com.redhat.ceylon.langtools.tools.javac.util.ListBuffer;
import com.redhat.ceylon.langtools.tools.javac.util.Log;
import com.redhat.ceylon.langtools.tools.javac.util.Options;
import com.redhat.ceylon.model.typechecker.model.Module;
public class CeyloncFileManager extends JavacFileManager implements StandardJavaFileManager {
private Module currentModule;
private JarOutputRepositoryManager jarRepository;
private Context context;
private Options options;
private RepositoryManager repoManager;
private RepositoryManager outputRepoManager;
private Logger cmrLogger;
public CeyloncFileManager(Context context, boolean register, Charset charset) {
super(context, register, charset);
options = Options.instance(context);
}
private Logger getLogger(){
if(cmrLogger == null)
cmrLogger = new JavacLogger(options, Log.instance(context));
return cmrLogger;
}
private JarOutputRepositoryManager getJarRepository(){
if(jarRepository == null)
jarRepository = new JarOutputRepositoryManager(CeylonLog.instance(context), options, this, context.get(TaskListener.class));
return jarRepository;
}
public Context getContext() {
return context;
}
@Override
public void setContext(Context context) {
this.context = context;
super.setContext(context);
}
public JavaFileObject.Kind getKind(String name) {
if (name.endsWith(JavaFileObject.Kind.CLASS.extension))
return JavaFileObject.Kind.CLASS;
else if (name.endsWith(JavaFileObject.Kind.SOURCE.extension) || name.endsWith(".ceylon"))
return JavaFileObject.Kind.SOURCE;
else if (name.endsWith(JavaFileObject.Kind.HTML.extension))
return JavaFileObject.Kind.HTML;
else
return JavaFileObject.Kind.OTHER;
}
/**
* Register a Context.Factory to create a JavacFileManager.
*/
public static void preRegister(final Context context) {
context.put(JavaFileManager.class, new Context.Factory() {
public JavaFileManager make(Context context) {
return new CeyloncFileManager(context, true, null);
}
});
}
public Iterable extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable extends File> files) {
Iterable extends JavaFileObject> theCollection = super.getJavaFileObjectsFromFiles(files);
ArrayList result = new ArrayList();
for (JavaFileObject file : theCollection) {
if (file.getName().endsWith(".ceylon")) {
result.add(new CeylonFileObject(file));
} else {
result.add(file);
}
}
return result;
}
public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException {
Iterable result = super.list(location, packageName, kinds, recurse);
ListBuffer buf = new ListBuffer();
for (JavaFileObject f : result) {
if (f.getName().endsWith(".ceylon")) {
buf.add(new CeylonFileObject(f));
} else {
buf.add(f);
}
}
return buf.toList();
}
public String inferBinaryName(Location location, JavaFileObject file) {
if (file instanceof CeylonFileObject) {
CeylonFileObject fo = (CeylonFileObject) file;
return super.inferBinaryName(location, fo.getFile());
}
return super.inferBinaryName(location, file);
}
@Override
protected JavaFileObject getFileForOutput(Location location, RelativeFile fileName, FileObject sibling) throws IOException {
if (sibling instanceof CeylonFileObject) {
sibling = ((CeylonFileObject) sibling).getFile();
}
String quotedFileName = quoteKeywordsInFilename(fileName);
if(location == StandardLocation.CLASS_OUTPUT){
File siblingFile = null;
if (sibling != null && sibling instanceof RegularFileObject) {
siblingFile = ((RegularFileObject)sibling).getUnderlyingFile();
}
return getJarRepository().getFileObject(getOutputRepositoryManager(), currentModule, quotedFileName, siblingFile);
}else
return super.getFileForOutput(location, fileName, sibling);
}
private String quoteKeywordsInFilename(RelativeFile fileName) {
// internally, RelativeFile.path always uses '/' and not the platform separator
String path = fileName.getPath();
StringBuilder sb = new StringBuilder();
String[] parts = path.split("/");
for (String part : parts) {
sb.append(Util.quoteIfJavaKeyword(part)).append(File.separatorChar);
}
return sb.subSequence(0, sb.length() - 1).toString();
}
@Override
public JavaFileObject getJavaFileForInput(Location location,
String className,
JavaFileObject.Kind kind) throws IOException {
nullCheck(location);
// validateClassName(className);
nullCheck(className);
nullCheck(kind);
if (!sourceOrClass.contains(kind))
throw new IllegalArgumentException("Invalid kind " + kind);
JavaFileObject file = getFileForInput(location, forClass(className, kind));
if (file != null && file.getName().endsWith(".ceylon")) {
return new CeylonFileObject(file);
} else {
return file;
}
}
static RelativeFile forClass(CharSequence className, JavaFileObject.Kind kind) {
String extension;
if(kind == Kind.SOURCE)
extension = ".ceylon";
else
extension = kind.extension;
return new RelativeFile(className.toString().replace('.', '/') + extension);
}
@Override
public void flush() throws IOException {
super.flush();
try{
getJarRepository().flush();
}finally{
clearOutputRepositoryManager();
}
}
private void clearOutputRepositoryManager() {
if(outputRepoManager instanceof CachingRepositoryManager){
File tmpDir = ((CachingRepositoryManager)outputRepoManager).getCacheFolder();
FileUtil.delete(tmpDir);
// invalidate it
outputRepoManager = null;
}
}
public void setModule(Module module) {
currentModule = module;
}
public RepositoryManager getRepositoryManager() {
// caching
if(repoManager != null)
return repoManager;
// lazy loading
// any user defined repos
List userRepos = new LinkedList();
userRepos.addAll(options.getMulti(OptionName.CEYLONREPO));
String systemRepo = getSystemRepoOption();
String cacheRepo = getCacheRepoOption();
String outRepo = getOutputRepoOption();
String overrides = options.get(OptionName.CEYLONOVERRIDES);
boolean upgradeDist = !options.getBoolean(OptionName.CEYLONDOWNGRADEDIST.optionName);
repoManager = CeylonUtils.repoManager()
.config(CompilerConfig.instance(context))
.cwd(getCurrentWorkingDir())
.upgradeDist(upgradeDist)
.overrides(overrides)
.systemRepo(systemRepo)
.cacheRepo(cacheRepo)
.noDefaultRepos(getNoDefaultRepos())
.userRepos(userRepos)
.outRepo(outRepo)
.offline(getOfflineOption())
.timeout(getTimeoutOption())
.logger(getLogger())
.buildManager();
return repoManager;
}
public RepositoryManager getOutputRepositoryManager() {
// caching
if(outputRepoManager != null)
return outputRepoManager;
// lazy loading
// any user defined repos
String outRepo = getOutputRepoOption();
// username and password for WebDAV
String user = options.get(OptionName.CEYLONUSER);
String password = options.get(OptionName.CEYLONPASS);
outputRepoManager = CeylonUtils.repoManager()
.config(CompilerConfig.instance(context))
.cwd(getCurrentWorkingDir())
.outRepo(outRepo)
.logger(getLogger())
.user(user)
.password(password)
.timeout(getTimeoutOption())
.buildOutputManager();
return outputRepoManager;
}
protected String getCurrentWorkingDir() {
return options.get(OptionName.CEYLONCWD);
}
private String getSystemRepoOption() {
return options.get(OptionName.CEYLONSYSTEMREPO);
}
private String getCacheRepoOption() {
return options.get(OptionName.CEYLONCACHEREPO);
}
private boolean getNoDefaultRepos() {
return options.get(OptionName.CEYLONNODEFREPOS) != null;
}
private String getOutputRepoOption() {
// we use D and not CEYLONOUT here since that's where the option is stored
return options.get(OptionName.D);
}
private boolean getOfflineOption() {
return options.get(OptionName.CEYLONOFFLINE) != null;
}
private int getTimeoutOption() {
String to = options.get(OptionName.CEYLONTIMEOUT);
if(to != null){
return Integer.parseInt(to);
}
return -1;
}
@Override
protected File getClassOutDir() {
File outDir = super.getClassOutDir();
// set the default value for Ceylon
if (outDir == null) {
String dir = Repositories.withConfig(CompilerConfig.instance(context)).getOutputRepository().getUrl();
classOutDir = new File(dir);
}
return outDir;
}
@Override
protected boolean isValidDirectory(String s) {
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy