Refactor cli: all the jvm stuff goes under org.jetbrains.jet.cli.jvm, common stuff under org.jetbrains.jet.cli.common
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@ classpath="$classpath:$root/lib/*:$ideaRoot/lib/*:$ideaRoot/lib/rt/*"
|
||||
|
||||
exec java $JAVA_OPTS \
|
||||
-classpath "$classpath" \
|
||||
org.jetbrains.jet.cli.KotlinCompiler \
|
||||
org.jetbrains.jet.cli.jvm.K2JVMCompiler \
|
||||
"$@"
|
||||
|
||||
# vim: set ts=4 sw=4 et:
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.apache.tools.ant.Task;
|
||||
import org.apache.tools.ant.types.Path;
|
||||
import org.apache.tools.ant.types.Reference;
|
||||
import org.jetbrains.jet.buildtools.core.BytecodeCompiler;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentException;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
@@ -19,8 +19,9 @@ package org.jetbrains.jet.buildtools.core;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.compiler.*;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.*;
|
||||
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
|
||||
@@ -41,7 +42,7 @@ public class BytecodeCompiler {
|
||||
|
||||
|
||||
/**
|
||||
* Creates new instance of {@link org.jetbrains.jet.compiler.CompileEnvironmentConfiguration} instance using the arguments specified.
|
||||
* Creates new instance of {@link org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration} instance using the arguments specified.
|
||||
*
|
||||
* @param stdlib path to "kotlin-runtime.jar", only used if not null and not empty
|
||||
* @param classpath compilation classpath, only used if not null and not empty
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<target name="compileStdlib" depends="jar,jarLang,compileRT">
|
||||
<mkdir dir="${output}/classes/stdlib"/>
|
||||
<java classname="org.jetbrains.jet.cli.KotlinCompiler" failonerror="true" fork="true">
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true" fork="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<target name="compileJDKHeaders" depends="jar,jarLang">
|
||||
<mkdir dir="${output}/classes/stdlib"/>
|
||||
<java classname="org.jetbrains.jet.cli.KotlinCompiler" failonerror="true">
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
@@ -88,7 +88,7 @@
|
||||
|
||||
<target name="compileLang" depends="jar">
|
||||
<mkdir dir="${output}/classes/lang"/>
|
||||
<java classname="org.jetbrains.jet.cli.KotlinCompiler" failonerror="true">
|
||||
<java classname="org.jetbrains.jet.cli.jvm.K2JVMCompiler" failonerror="true">
|
||||
<classpath>
|
||||
<path refid="classpath"/>
|
||||
<pathelement location="${kotlin-home}/lib/kotlin-compiler.jar"/>
|
||||
@@ -210,7 +210,7 @@
|
||||
<attribute name="Implementation-Title" value="Kotlin Compiler"/>
|
||||
<attribute name="Implementation-Version" value="${build.number}"/>
|
||||
|
||||
<attribute name="Main-Class" value="org.jetbrains.jet.cli.KotlinCompiler"/>
|
||||
<attribute name="Main-Class" value="org.jetbrains.jet.cli.jvm.K2JVMCompiler"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko, Alefas
|
||||
*/
|
||||
public final class TipsManager {
|
||||
|
||||
private TipsManager() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) {
|
||||
JetExpression receiverExpression = expression.getReceiverExpression();
|
||||
if (receiverExpression != null) {
|
||||
// Process as call expression
|
||||
final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||
|
||||
if (expressionType != null && resolutionScope != null) {
|
||||
if (!(expressionType instanceof NamespaceType)) {
|
||||
ExpressionReceiver receiverDescriptor = new ExpressionReceiver(receiverExpression, expressionType);
|
||||
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
|
||||
|
||||
DataFlowInfo info = context.get(BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW, expression);
|
||||
if (info == null) {
|
||||
info = DataFlowInfo.EMPTY;
|
||||
}
|
||||
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(info, context);
|
||||
List<ReceiverDescriptor> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiverDescriptor);
|
||||
|
||||
for (ReceiverDescriptor descriptor : variantsForExplicitReceiver) {
|
||||
descriptors.addAll(includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(descriptor.getType().getMemberScope().getAllDescriptors()),
|
||||
resolutionScope, descriptor));
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
return includeExternalCallableExtensions(
|
||||
excludePrivateDescriptors(expressionType.getMemberScope().getAllDescriptors()),
|
||||
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
else {
|
||||
return getVariantsNoReceiver(expression, context);
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection<DeclarationDescriptor> getVariantsNoReceiver(JetExpression expression, BindingContext context) {
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
if (resolutionScope != null) {
|
||||
if (expression.getParent() instanceof JetImportDirective || expression.getParent() instanceof JetNamespaceHeader) {
|
||||
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors());
|
||||
}
|
||||
else {
|
||||
HashSet<DeclarationDescriptor> descriptorsSet = Sets.newHashSet();
|
||||
|
||||
ArrayList<ReceiverDescriptor> result = new ArrayList<ReceiverDescriptor>();
|
||||
resolutionScope.getImplicitReceiversHierarchy(result);
|
||||
|
||||
for (ReceiverDescriptor receiverDescriptor : result) {
|
||||
JetType receiverType = receiverDescriptor.getType();
|
||||
descriptorsSet.addAll(receiverType.getMemberScope().getAllDescriptors());
|
||||
}
|
||||
|
||||
descriptorsSet.addAll(resolutionScope.getAllDescriptors());
|
||||
return excludeNotCallableExtensions(excludePrivateDescriptors(descriptorsSet), resolutionScope);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Collection<DeclarationDescriptor> getReferenceVariants(JetNamespaceHeader expression, BindingContext context) {
|
||||
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
|
||||
if (resolutionScope != null) {
|
||||
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors());
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static Collection<DeclarationDescriptor> excludePrivateDescriptors(
|
||||
@NotNull Collection<DeclarationDescriptor> descriptors) {
|
||||
|
||||
return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) descriptor;
|
||||
if (namespaceDescriptor.getName().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Collection<DeclarationDescriptor> excludeNotCallableExtensions(
|
||||
@NotNull Collection<? extends DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
||||
) {
|
||||
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
final ArrayList<ReceiverDescriptor> result = new ArrayList<ReceiverDescriptor>();
|
||||
scope.getImplicitReceiversHierarchy(result);
|
||||
|
||||
descriptorsSet.removeAll(
|
||||
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||
if (!callableDescriptor.getReceiverParameter().exists()) {
|
||||
return false;
|
||||
}
|
||||
for (ReceiverDescriptor receiverDescriptor : result) {
|
||||
if (ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor, callableDescriptor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
return Lists.newArrayList(descriptorsSet);
|
||||
}
|
||||
|
||||
private static Collection<DeclarationDescriptor> excludeNonPackageDescriptors(
|
||||
@NotNull Collection<DeclarationDescriptor> descriptors) {
|
||||
return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(DeclarationDescriptor declarationDescriptor) {
|
||||
return declarationDescriptor instanceof NamespaceDescriptor;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Set<DeclarationDescriptor> includeExternalCallableExtensions(
|
||||
@NotNull Collection<DeclarationDescriptor> descriptors,
|
||||
@NotNull final JetScope externalScope,
|
||||
@NotNull final ReceiverDescriptor receiverDescriptor
|
||||
) {
|
||||
// It's impossible to add extension function for namespace
|
||||
JetType receiverType = receiverDescriptor.getType();
|
||||
if (receiverType instanceof NamespaceType) {
|
||||
return new HashSet<DeclarationDescriptor>(descriptors);
|
||||
}
|
||||
|
||||
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||
|
||||
descriptorsSet.addAll(
|
||||
Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||
new Predicate<CallableDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||
return ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor, callableDescriptor);
|
||||
}
|
||||
}));
|
||||
|
||||
return descriptorsSet;
|
||||
}
|
||||
}
|
||||
@@ -95,4 +95,4 @@ CPSELECT="-cp "
|
||||
$JAVA_OPTS \
|
||||
"${java_args[@]}" \
|
||||
${CPSELECT}${TOOL_CLASSPATH} \
|
||||
org.jetbrains.jet.cli.KotlinCompiler "$@"
|
||||
org.jetbrains.jet.cli.jvm.K2JVMCompiler "$@"
|
||||
|
||||
@@ -27,7 +27,7 @@ if "%_TOOL_CLASSPATH%"=="" (
|
||||
for /d %%f in ("%_KOTLIN_HOME%\lib\*") do call :add_cpath "%%f"
|
||||
)
|
||||
|
||||
"%_JAVACMD%" %_JAVA_OPTS% -cp "%_TOOL_CLASSPATH%" org.jetbrains.jet.cli.KotlinCompiler %*
|
||||
"%_JAVACMD%" %_JAVA_OPTS% -cp "%_TOOL_CLASSPATH%" org.jetbrains.jet.cli.jvm.K2JVMCompiler %*
|
||||
goto end
|
||||
|
||||
rem ##########################################################################
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* 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.jetbrains.jet.cli;
|
||||
|
||||
import com.sampullara.cli.Argument;
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command line arguments for the {@link KotlinCompiler}
|
||||
*/
|
||||
public class CompilerArguments {
|
||||
private List<CompilerPlugin> compilerPlugins = new ArrayList<CompilerPlugin>();
|
||||
|
||||
// TODO ideally we'd unify this with 'src' to just having a single field that supports multiple files/dirs
|
||||
private List<String> sourceDirs;
|
||||
|
||||
public List<String> getSourceDirs() {
|
||||
return sourceDirs;
|
||||
}
|
||||
|
||||
public void setSourceDirs(List<String> sourceDirs) {
|
||||
this.sourceDirs = sourceDirs;
|
||||
}
|
||||
|
||||
@Argument(value = "output", description = "output directory")
|
||||
public String outputDir;
|
||||
|
||||
@Argument(value = "jar", description = "jar file name")
|
||||
public String jar;
|
||||
|
||||
@Argument(value = "src", description = "source file or directory")
|
||||
public String src;
|
||||
|
||||
@Argument(value = "module", description = "module to compile")
|
||||
public String module;
|
||||
|
||||
@Argument(value = "classpath", description = "classpath to use when compiling")
|
||||
public String classpath;
|
||||
|
||||
@Argument(value = "includeRuntime", description = "include Kotlin runtime in to resulting jar")
|
||||
public boolean includeRuntime;
|
||||
|
||||
@Argument(value = "stdlib", description = "Path to the stdlib.jar")
|
||||
public String stdlib;
|
||||
|
||||
@Argument(value = "jdkHeaders", description = "Path to the kotlin-jdk-headers.jar")
|
||||
public String jdkHeaders;
|
||||
|
||||
@Argument(value = "help", alias = "h", description = "show help")
|
||||
public boolean help;
|
||||
|
||||
@Argument(value = "mode", description = "Special compiler modes: stubs or jdkHeaders")
|
||||
public String mode;
|
||||
|
||||
@Argument(value = "tags", description = "Demarcate each compilation message (error, warning, etc) with an open and close tag")
|
||||
public boolean tags;
|
||||
|
||||
@Argument(value = "verbose", description = "Enable verbose logging output")
|
||||
public boolean verbose;
|
||||
|
||||
@Argument(value = "version", description = "Display compiler version")
|
||||
public boolean version;
|
||||
|
||||
|
||||
public String getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
public void setClasspath(String classpath) {
|
||||
this.classpath = classpath;
|
||||
}
|
||||
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
public void setHelp(boolean help) {
|
||||
this.help = help;
|
||||
}
|
||||
|
||||
public boolean isIncludeRuntime() {
|
||||
return includeRuntime;
|
||||
}
|
||||
|
||||
public void setIncludeRuntime(boolean includeRuntime) {
|
||||
this.includeRuntime = includeRuntime;
|
||||
}
|
||||
|
||||
public String getJar() {
|
||||
return jar;
|
||||
}
|
||||
|
||||
public void setJar(String jar) {
|
||||
this.jar = jar;
|
||||
}
|
||||
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
public void setModule(String module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
public void setOutputDir(String outputDir) {
|
||||
this.outputDir = outputDir;
|
||||
}
|
||||
|
||||
public String getSrc() {
|
||||
return src;
|
||||
}
|
||||
|
||||
public void setSrc(String src) {
|
||||
this.src = src;
|
||||
}
|
||||
|
||||
public String getStdlib() {
|
||||
return stdlib;
|
||||
}
|
||||
|
||||
public void setStdlib(String stdlib) {
|
||||
this.stdlib = stdlib;
|
||||
}
|
||||
|
||||
public boolean isTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(boolean tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public List<CompilerPlugin> getCompilerPlugins() {
|
||||
return compilerPlugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the compiler plugins to be used when working with the {@link KotlinCompiler}
|
||||
*/
|
||||
public void setCompilerPlugins(List<CompilerPlugin> compilerPlugins) {
|
||||
this.compilerPlugins = compilerPlugins;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.cli;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompilerVersion {
|
||||
// The value of this constant is generated by the build script
|
||||
// DON'T MODIFY IT
|
||||
public static final String VERSION = "@snapshot@";
|
||||
}
|
||||
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.cli;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.sampullara.cli.Args;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.CompilationException;
|
||||
import org.jetbrains.jet.compiler.*;
|
||||
import org.jetbrains.jet.compiler.messages.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.cli.KotlinCompiler.ExitCode.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public class KotlinCompiler {
|
||||
|
||||
public enum ExitCode {
|
||||
OK(0),
|
||||
COMPILATION_ERROR(1),
|
||||
INTERNAL_ERROR(2);
|
||||
|
||||
private final int code;
|
||||
|
||||
private ExitCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
doMain(new KotlinCompiler(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful main for derived command line tools
|
||||
*/
|
||||
public static void doMain(KotlinCompiler compiler, String[] args) {
|
||||
try {
|
||||
ExitCode rc = compiler.exec(System.out, args);
|
||||
if (rc != OK) {
|
||||
System.err.println("exec() finished with " + rc + " return code");
|
||||
System.exit(rc.getCode());
|
||||
}
|
||||
}
|
||||
catch (CompileEnvironmentException e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.exit(INTERNAL_ERROR.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public ExitCode exec(PrintStream errStream, String... args) {
|
||||
CompilerArguments arguments = createArguments();
|
||||
if (!parseArguments(errStream, arguments, args)) {
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
return exec(errStream, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the compiler on the parsed arguments
|
||||
*/
|
||||
public ExitCode exec(final PrintStream errStream, CompilerArguments arguments) {
|
||||
if (arguments.help) {
|
||||
usage(errStream);
|
||||
return OK;
|
||||
}
|
||||
System.setProperty("java.awt.headless", "true");
|
||||
|
||||
final MessageRenderer messageRenderer = arguments.tags ? MessageRenderer.TAGS : MessageRenderer.PLAIN;
|
||||
|
||||
errStream.print(messageRenderer.renderPreamble());
|
||||
|
||||
try {
|
||||
if (arguments.version) {
|
||||
errStream.println(messageRenderer.render(CompilerMessageSeverity.INFO, "Kotlin Compiler version " + CompilerVersion.VERSION, CompilerMessageLocation.NO_LOCATION));
|
||||
}
|
||||
|
||||
CompilerSpecialMode mode = parseCompilerSpecialMode(arguments);
|
||||
|
||||
File jdkHeadersJar;
|
||||
if (mode.includeJdkHeaders()) {
|
||||
if (arguments.jdkHeaders != null) {
|
||||
jdkHeadersJar = new File(arguments.jdkHeaders);
|
||||
}
|
||||
else {
|
||||
jdkHeadersJar = PathUtil.getAltHeadersPath();
|
||||
}
|
||||
}
|
||||
else {
|
||||
jdkHeadersJar = null;
|
||||
}
|
||||
File runtimeJar;
|
||||
|
||||
if (mode.includeKotlinRuntime()) {
|
||||
if (arguments.stdlib != null) {
|
||||
runtimeJar = new File(arguments.stdlib);
|
||||
}
|
||||
else {
|
||||
runtimeJar = PathUtil.getDefaultRuntimePath();
|
||||
}
|
||||
}
|
||||
else {
|
||||
runtimeJar = null;
|
||||
}
|
||||
|
||||
CompilerDependencies dependencies = new CompilerDependencies(mode, CompilerDependencies.findRtJar(), jdkHeadersJar, runtimeJar);
|
||||
PrintingMessageCollector messageCollector = new PrintingMessageCollector(errStream, messageRenderer, arguments.verbose);
|
||||
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
|
||||
|
||||
JetCoreEnvironment environment = new JetCoreEnvironment(rootDisposable, dependencies);
|
||||
CompileEnvironmentConfiguration configuration = new CompileEnvironmentConfiguration(environment, dependencies, messageCollector);
|
||||
|
||||
messageCollector.report(CompilerMessageSeverity.LOGGING, "Configuring the compilation environment",
|
||||
CompilerMessageLocation.NO_LOCATION);
|
||||
try {
|
||||
configureEnvironment(configuration, arguments);
|
||||
|
||||
boolean noErrors;
|
||||
if (arguments.module != null) {
|
||||
List<Module> modules = CompileEnvironmentUtil.loadModuleScript(arguments.module, new PrintingMessageCollector(errStream, messageRenderer, false));
|
||||
File directory = new File(arguments.module).getParentFile();
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileModules(configuration, modules,
|
||||
directory, arguments.jar, arguments.outputDir,
|
||||
arguments.includeRuntime);
|
||||
}
|
||||
else {
|
||||
// TODO ideally we'd unify to just having a single field that supports multiple files/dirs
|
||||
if (arguments.getSourceDirs() != null) {
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSourceDirectories(configuration,
|
||||
arguments.getSourceDirs(), arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
}
|
||||
else {
|
||||
noErrors = KotlinToJVMBytecodeCompiler.compileBunchOfSources(configuration,
|
||||
arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime);
|
||||
}
|
||||
}
|
||||
return noErrors ? OK : COMPILATION_ERROR;
|
||||
}
|
||||
catch (CompilationException e) {
|
||||
messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(e),
|
||||
MessageUtil.psiElementToMessageLocation(e.getElement()));
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
messageCollector.report(CompilerMessageSeverity.EXCEPTION, MessageRenderer.PLAIN.renderException(t), CompilerMessageLocation.NO_LOCATION);
|
||||
return INTERNAL_ERROR;
|
||||
}
|
||||
finally {
|
||||
Disposer.dispose(rootDisposable);
|
||||
messageCollector.printToErrStream();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
errStream.print(messageRenderer.renderConclusion());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CompilerSpecialMode parseCompilerSpecialMode(@NotNull CompilerArguments arguments) {
|
||||
if (arguments.mode == null) {
|
||||
return CompilerSpecialMode.REGULAR;
|
||||
}
|
||||
else {
|
||||
for (CompilerSpecialMode variant : CompilerSpecialMode.values()) {
|
||||
if (arguments.mode.equalsIgnoreCase(variant.name().replaceAll("_", ""))) {
|
||||
return variant;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: report properly
|
||||
throw new IllegalArgumentException("unknown compiler mode: " + arguments.mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the arguments can be parsed correctly
|
||||
*/
|
||||
protected boolean parseArguments(PrintStream errStream, CompilerArguments arguments, String[] args) {
|
||||
try {
|
||||
Args.parse(arguments, args);
|
||||
return true;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
usage(errStream);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
// Always use tags
|
||||
errStream.println(MessageRenderer.TAGS.renderException(t));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void usage(PrintStream target) {
|
||||
// We should say something like
|
||||
// Args.usage(target, CompilerArguments.class);
|
||||
// but currently cli-parser we are using does not support that
|
||||
// a corresponding patch has been sent to the authors
|
||||
// For now, we are using this:
|
||||
|
||||
PrintStream oldErr = System.err;
|
||||
System.setErr(target);
|
||||
try {
|
||||
// TODO: use proper argv0
|
||||
Args.usage(new CompilerArguments());
|
||||
} finally {
|
||||
System.setErr(oldErr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow derived classes to add additional command line arguments
|
||||
*/
|
||||
protected CompilerArguments createArguments() {
|
||||
return new CompilerArguments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy method to configure the environment, allowing compiler
|
||||
* based tools to customise their own plugins
|
||||
*/
|
||||
protected void configureEnvironment(CompileEnvironmentConfiguration configuration, CompilerArguments arguments) {
|
||||
// install any compiler plugins
|
||||
List<CompilerPlugin> plugins = arguments.getCompilerPlugins();
|
||||
if (plugins != null) {
|
||||
configuration.getCompilerPlugins().addAll(plugins);
|
||||
}
|
||||
|
||||
if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
|
||||
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
|
||||
}
|
||||
|
||||
if (arguments.classpath != null) {
|
||||
final Iterable<String> classpath = Splitter.on(File.pathSeparatorChar).split(arguments.classpath);
|
||||
CompileEnvironmentUtil.addToClasspath(configuration.getEnvironment(), Iterables.toArray(classpath, String.class));
|
||||
}
|
||||
}
|
||||
|
||||
private static class PrintingMessageCollector implements MessageCollector {
|
||||
private final boolean verbose;
|
||||
private final PrintStream errStream;
|
||||
private final MessageRenderer messageRenderer;
|
||||
|
||||
// File path (nullable) -> error message
|
||||
private final Multimap<String, String> groupedMessages = LinkedHashMultimap.create();
|
||||
|
||||
public PrintingMessageCollector(PrintStream errStream,
|
||||
MessageRenderer messageRenderer,
|
||||
boolean verbose) {
|
||||
this.verbose = verbose;
|
||||
this.errStream = errStream;
|
||||
this.messageRenderer = messageRenderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(@NotNull CompilerMessageSeverity severity,
|
||||
@NotNull String message,
|
||||
@NotNull CompilerMessageLocation location) {
|
||||
String text = messageRenderer.render(severity, message, location);
|
||||
if (severity == CompilerMessageSeverity.LOGGING) {
|
||||
if (!verbose) {
|
||||
return;
|
||||
}
|
||||
errStream.println(text);
|
||||
}
|
||||
groupedMessages.put(location.getPath(), text);
|
||||
}
|
||||
|
||||
public void printToErrStream() {
|
||||
if (!groupedMessages.isEmpty()) {
|
||||
for (String path : groupedMessages.keySet()) {
|
||||
Collection<String> messageTexts = groupedMessages.get(path);
|
||||
for (String text : messageTexts) {
|
||||
errStream.println(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class CliJetFilesProvider extends JetFilesProvider {
|
||||
private final JetCoreEnvironment environment;
|
||||
private Function<JetFile,Collection<JetFile>> all_files = new Function<JetFile, Collection<JetFile>>() {
|
||||
@Override
|
||||
public Collection<JetFile> fun(JetFile file) {
|
||||
return environment.getSourceFiles();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public CliJetFilesProvider(JetCoreEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<JetFile, Collection<JetFile>> sampleToAllFilesInModule() {
|
||||
return all_files;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JetFile> allInScope(GlobalSearchScope scope) {
|
||||
List<JetFile> answer = new ArrayList<JetFile>();
|
||||
for (JetFile file : environment.getSourceFiles()) {
|
||||
if (scope.contains(file.getVirtualFile())) {
|
||||
answer.add(file);
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompileEnvironmentConfiguration {
|
||||
private final JetCoreEnvironment environment;
|
||||
private final CompilerDependencies compilerDependencies;
|
||||
private final MessageCollector messageCollector;
|
||||
|
||||
private List<CompilerPlugin> compilerPlugins = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
|
||||
* @see Disposer
|
||||
*/
|
||||
public CompileEnvironmentConfiguration(@NotNull JetCoreEnvironment environment,
|
||||
@NotNull CompilerDependencies compilerDependencies, @NotNull MessageCollector messageCollector) {
|
||||
this.messageCollector = messageCollector;
|
||||
this.compilerDependencies = compilerDependencies;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public JetCoreEnvironment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompilerDependencies getCompilerDependencies() {
|
||||
return compilerDependencies;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MessageCollector getMessageCollector() {
|
||||
return messageCollector;
|
||||
}
|
||||
|
||||
public List<CompilerPlugin> getCompilerPlugins() {
|
||||
return compilerPlugins;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class CompileEnvironmentException extends RuntimeException {
|
||||
public CompileEnvironmentException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CompileEnvironmentException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CompileEnvironmentException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.Processor;
|
||||
import jet.modules.AllModules;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GeneratedClassLoader;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.*;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompileEnvironmentUtil {
|
||||
public static Disposable createMockDisposable() {
|
||||
return new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getUnpackedRuntimePath() {
|
||||
URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
if (url != null && url.getProtocol().equals("file")) {
|
||||
return new File(url.getPath()).getParentFile().getParentFile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getRuntimeJarPath() {
|
||||
URL url = CompileEnvironmentConfiguration.class.getClassLoader().getResource("jet/JetObject.class");
|
||||
if (url != null && url.getProtocol().equals("jar")) {
|
||||
String path = url.getPath();
|
||||
return new File(path.substring(path.indexOf(":") + 1, path.indexOf("!/")));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ensureKotlinRuntime(JetCoreEnvironment env) {
|
||||
if (JavaPsiFacade.getInstance(env.getProject()).findClass("jet.JetObject", GlobalSearchScope.allScope(env.getProject())) == null) {
|
||||
// TODO: prepend
|
||||
File kotlin = PathUtil.getDefaultRuntimePath();
|
||||
if (kotlin == null || !kotlin.exists()) {
|
||||
kotlin = getUnpackedRuntimePath();
|
||||
if (kotlin == null) kotlin = getRuntimeJarPath();
|
||||
}
|
||||
if (kotlin == null) {
|
||||
throw new IllegalStateException("kotlin runtime not found");
|
||||
}
|
||||
env.addToClasspath(kotlin);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ensureRuntime(JetCoreEnvironment environment, CompilerDependencies compilerDependencies) {
|
||||
if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.REGULAR) {
|
||||
ensureKotlinRuntime(environment);
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.JDK_HEADERS) {
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.STDLIB) {
|
||||
}
|
||||
else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.BUILTINS) {
|
||||
// nop
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("unknown mode: " + compilerDependencies.getCompilerSpecialMode());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Module> loadModuleScript(String moduleScriptFile, MessageCollector messageCollector) {
|
||||
Disposable disposable = new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
};
|
||||
CompilerDependencies dependencies = CompilerDependencies.compilerDependenciesForProduction(CompilerSpecialMode.REGULAR);
|
||||
JetCoreEnvironment scriptEnvironment = new JetCoreEnvironment(disposable, dependencies);
|
||||
ensureRuntime(scriptEnvironment, dependencies);
|
||||
scriptEnvironment.addSources(moduleScriptFile);
|
||||
|
||||
GenerationState generationState = KotlinToJVMBytecodeCompiler
|
||||
.analyzeAndGenerate(new CompileEnvironmentConfiguration(scriptEnvironment, dependencies, messageCollector), false);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Module> modules = runDefineModules(dependencies, moduleScriptFile, generationState.getFactory());
|
||||
|
||||
Disposer.dispose(disposable);
|
||||
|
||||
if (modules == null) {
|
||||
throw new CompileEnvironmentException("Module script " + moduleScriptFile + " compilation failed");
|
||||
}
|
||||
|
||||
if (modules.isEmpty()) {
|
||||
throw new CompileEnvironmentException("No modules where defined by " + moduleScriptFile);
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
private static List<Module> runDefineModules(CompilerDependencies compilerDependencies, String moduleFile, ClassFileFactory factory) {
|
||||
File stdlibJar = compilerDependencies.getRuntimeJar();
|
||||
GeneratedClassLoader loader;
|
||||
if (stdlibJar != null) {
|
||||
try {
|
||||
loader = new GeneratedClassLoader(factory, new URLClassLoader(new URL[]{stdlibJar.toURI().toURL()}, AllModules.class.getClassLoader()));
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
loader = new GeneratedClassLoader(factory, CompileEnvironmentConfiguration.class.getClassLoader());
|
||||
}
|
||||
try {
|
||||
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
|
||||
final Method method = namespaceClass.getDeclaredMethod("project");
|
||||
if (method == null) {
|
||||
throw new CompileEnvironmentException("Module script " + moduleFile + " must define project() function");
|
||||
}
|
||||
|
||||
method.setAccessible(true);
|
||||
method.invoke(null);
|
||||
|
||||
ArrayList<Module> answer = new ArrayList<Module>(AllModules.modules.get());
|
||||
AllModules.modules.get().clear();
|
||||
return answer;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ModuleExecutionException(e);
|
||||
}
|
||||
finally {
|
||||
loader.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToJar(ClassFileFactory factory, final OutputStream fos, @Nullable FqName mainClass, boolean includeRuntime) {
|
||||
try {
|
||||
Manifest manifest = new Manifest();
|
||||
final Attributes mainAttributes = manifest.getMainAttributes();
|
||||
mainAttributes.putValue("Manifest-Version", "1.0");
|
||||
mainAttributes.putValue("Created-By", "JetBrains Kotlin");
|
||||
if (mainClass != null) {
|
||||
mainAttributes.putValue("Main-Class", mainClass.getFqName());
|
||||
}
|
||||
JarOutputStream stream = new JarOutputStream(fos, manifest);
|
||||
try {
|
||||
for (String file : factory.files()) {
|
||||
stream.putNextEntry(new JarEntry(file));
|
||||
stream.write(factory.asBytes(file));
|
||||
}
|
||||
if (includeRuntime) {
|
||||
writeRuntimeToJar(stream);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new CompileEnvironmentException("Failed to generate jar file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeRuntimeToJar(final JarOutputStream stream) throws IOException {
|
||||
final File unpackedRuntimePath = getUnpackedRuntimePath();
|
||||
if (unpackedRuntimePath != null) {
|
||||
FileUtil.processFilesRecursively(unpackedRuntimePath, new Processor<File>() {
|
||||
@Override
|
||||
public boolean process(File file) {
|
||||
if (file.isDirectory()) return true;
|
||||
final String relativePath = FileUtil.getRelativePath(unpackedRuntimePath, file);
|
||||
try {
|
||||
stream.putNextEntry(new JarEntry(FileUtil.toSystemIndependentName(relativePath)));
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
try {
|
||||
FileUtil.copy(fis, stream);
|
||||
}
|
||||
finally {
|
||||
fis.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
File runtimeJarPath = getRuntimeJarPath();
|
||||
if (runtimeJarPath != null) {
|
||||
JarInputStream jis = new JarInputStream(new FileInputStream(runtimeJarPath));
|
||||
try {
|
||||
while (true) {
|
||||
JarEntry e = jis.getNextJarEntry();
|
||||
if (e == null) {
|
||||
break;
|
||||
}
|
||||
if (FileUtil.getExtension(e.getName()).equals("class")) {
|
||||
stream.putNextEntry(e);
|
||||
FileUtil.copy(jis, stream);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
jis.close();
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new CompileEnvironmentException("Couldn't find runtime library");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeToOutputDirectory(ClassFileFactory factory, final String outputDir) {
|
||||
List<String> files = factory.files();
|
||||
for (String file : files) {
|
||||
File target = new File(outputDir, file);
|
||||
try {
|
||||
FileUtil.writeToFile(target, factory.asBytes(file));
|
||||
} catch (IOException e) {
|
||||
throw new CompileEnvironmentException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param environment compilation environment to add to
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public static void addToClasspath(JetCoreEnvironment environment, File ... paths) {
|
||||
for (File path : paths) {
|
||||
if (!path.exists()) {
|
||||
throw new CompileEnvironmentException("'" + path + "' does not exist");
|
||||
}
|
||||
environment.addToClasspath(path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add path specified to the compilation environment.
|
||||
* @param environment compilation environment to add to
|
||||
* @param paths paths to add
|
||||
*/
|
||||
public static void addToClasspath(JetCoreEnvironment environment, String ... paths) {
|
||||
for (String path : paths) {
|
||||
addToClasspath(environment, new File(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
/**
|
||||
* A simple interface for compiler plugins to run after the compiler has finished such as for things like
|
||||
* generating documentation or code generation etc
|
||||
*/
|
||||
public interface CompilerPlugin {
|
||||
void processFiles(CompilerPluginContext context);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the context of available state in which a {@link CompilerPlugin} runs such as
|
||||
* the {@link Project}, the {@link BindingContext} and the underlying {@link JetFile} files.
|
||||
*/
|
||||
public class CompilerPluginContext {
|
||||
private final Project project;
|
||||
private final BindingContext context;
|
||||
private final List<JetFile> files;
|
||||
|
||||
public CompilerPluginContext(Project project, BindingContext context, List<JetFile> files) {
|
||||
this.project = project;
|
||||
this.context = context;
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
public BindingContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public List<JetFile> getFiles() {
|
||||
return files;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return project;
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.core.JavaCoreEnvironment;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.mock.MockApplication;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElementFinder;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.asJava.JavaElementFinder;
|
||||
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class JetCoreEnvironment extends JavaCoreEnvironment {
|
||||
private final List<JetFile> sourceFiles = new ArrayList<JetFile>();
|
||||
|
||||
public JetCoreEnvironment(Disposable parentDisposable, @NotNull CompilerDependencies compilerDependencies) {
|
||||
super(parentDisposable);
|
||||
registerFileType(JetFileType.INSTANCE, "kt");
|
||||
registerFileType(JetFileType.INSTANCE, "kts");
|
||||
registerFileType(JetFileType.INSTANCE, "ktm");
|
||||
registerFileType(JetFileType.INSTANCE, "jet");
|
||||
registerParserDefinition(new JavaParserDefinition());
|
||||
registerParserDefinition(new JetParserDefinition());
|
||||
|
||||
|
||||
myProject.registerService(JetFilesProvider.class, new CliJetFilesProvider(this));
|
||||
Extensions.getArea(myProject)
|
||||
.getExtensionPoint(PsiElementFinder.EP_NAME)
|
||||
.registerExtension(new JavaElementFinder(myProject));
|
||||
|
||||
CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
|
||||
|
||||
addToClasspath(compilerDependencies.getJdkJar());
|
||||
|
||||
if (compilerSpecialMode.includeJdkHeaders()) {
|
||||
for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) {
|
||||
addLibraryRoot(root);
|
||||
}
|
||||
}
|
||||
if (compilerSpecialMode.includeKotlinRuntime()) {
|
||||
for (VirtualFile root : compilerDependencies.getRuntimeRoots()) {
|
||||
addLibraryRoot(root);
|
||||
}
|
||||
}
|
||||
|
||||
JetStandardLibrary.initialize(getProject());
|
||||
}
|
||||
|
||||
public MockApplication getApplication() {
|
||||
return myApplication;
|
||||
}
|
||||
|
||||
private void addSources(File file) {
|
||||
if(file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File child : files) {
|
||||
addSources(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
VirtualFile fileByPath = getLocalFileSystem().findFileByPath(file.getAbsolutePath());
|
||||
if (fileByPath != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(fileByPath);
|
||||
if(psiFile instanceof JetFile) {
|
||||
sourceFiles.add((JetFile)psiFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addSources(VirtualFile vFile) {
|
||||
if (vFile.isDirectory()) {
|
||||
for (VirtualFile virtualFile : vFile.getChildren()) {
|
||||
addSources(virtualFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (vFile.getFileType() == JetFileType.INSTANCE) {
|
||||
PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(vFile);
|
||||
if (psiFile instanceof JetFile) {
|
||||
sourceFiles.add((JetFile)psiFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addSources(String path) {
|
||||
if(path == null)
|
||||
return;
|
||||
|
||||
VirtualFile vFile = getLocalFileSystem().findFileByPath(path);
|
||||
if (vFile == null) {
|
||||
throw new CompileEnvironmentException("File/directory not found: " + path);
|
||||
}
|
||||
if (!vFile.isDirectory() && vFile.getFileType() != JetFileType.INSTANCE) {
|
||||
throw new CompileEnvironmentException("Not a Kotlin file: " + path);
|
||||
}
|
||||
|
||||
addSources(new File(path));
|
||||
}
|
||||
|
||||
public List<JetFile> getSourceFiles() {
|
||||
return sourceFiles;
|
||||
}
|
||||
|
||||
public void addToClasspathFromClassLoader(ClassLoader loader) {
|
||||
ClassLoader parent = loader.getParent();
|
||||
if(parent != null)
|
||||
addToClasspathFromClassLoader(parent);
|
||||
|
||||
if(loader instanceof URLClassLoader) {
|
||||
for (URL url : ((URLClassLoader) loader).getURLs()) {
|
||||
File file = new File(url.getPath());
|
||||
if(file.exists() && (!file.isFile() || file.getPath().endsWith(".jar")))
|
||||
addToClasspath(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import jet.Function0;
|
||||
import jet.modules.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.compiler.messages.AnalyzerWithCompilerReport;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageLocation;
|
||||
import org.jetbrains.jet.compiler.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.jetbrains.jet.plugin.JetMainDetector;
|
||||
import org.jetbrains.jet.utils.Progress;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author abreslav
|
||||
*/
|
||||
public class KotlinToJVMBytecodeCompiler {
|
||||
|
||||
private KotlinToJVMBytecodeCompiler() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassFileFactory compileModule(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
Module moduleBuilder,
|
||||
File directory
|
||||
) {
|
||||
if (moduleBuilder.getSourceFiles().isEmpty()) {
|
||||
throw new CompileEnvironmentException("No source files where defined");
|
||||
}
|
||||
|
||||
for (String sourceFile : moduleBuilder.getSourceFiles()) {
|
||||
File source = new File(sourceFile);
|
||||
if (!source.isAbsolute()) {
|
||||
source = new File(directory, sourceFile);
|
||||
}
|
||||
|
||||
if (!source.exists()) {
|
||||
throw new CompileEnvironmentException("'" + source + "' does not exist");
|
||||
}
|
||||
|
||||
configuration.getEnvironment().addSources(source.getPath());
|
||||
}
|
||||
for (String classpathRoot : moduleBuilder.getClasspathRoots()) {
|
||||
configuration.getEnvironment().addToClasspath(new File(classpathRoot));
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
return generationState.getFactory();
|
||||
}
|
||||
|
||||
public static boolean compileModules(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
@NotNull List<Module> modules,
|
||||
|
||||
@NotNull File directory,
|
||||
@Nullable String jarPath,
|
||||
@Nullable String outputDir,
|
||||
boolean jarRuntime) {
|
||||
|
||||
for (Module moduleBuilder : modules) {
|
||||
// TODO: this should be done only once for the environment
|
||||
if (configuration.getCompilerDependencies().getRuntimeJar() != null) {
|
||||
CompileEnvironmentUtil
|
||||
.addToClasspath(configuration.getEnvironment(), configuration.getCompilerDependencies().getRuntimeJar());
|
||||
}
|
||||
ClassFileFactory moduleFactory = compileModule(configuration, moduleBuilder, directory);
|
||||
if (moduleFactory == null) {
|
||||
return false;
|
||||
}
|
||||
if (outputDir != null) {
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(moduleFactory, outputDir);
|
||||
}
|
||||
else {
|
||||
String path = jarPath != null ? jarPath : new File(directory, moduleBuilder.getModuleName() + ".jar").getPath();
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(moduleFactory, new FileOutputStream(path), null, jarRuntime);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean compileBunchOfSources(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
String jar,
|
||||
String outputDir,
|
||||
boolean includeRuntime
|
||||
) {
|
||||
FqName mainClass = null;
|
||||
for (JetFile file : configuration.getEnvironment().getSourceFiles()) {
|
||||
if (JetMainDetector.hasMain(file.getDeclarations())) {
|
||||
FqName fqName = JetPsiUtil.getFQName(file);
|
||||
mainClass = fqName.child(JvmAbi.PACKAGE_CLASS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CompileEnvironmentUtil.ensureRuntime(configuration.getEnvironment(), configuration.getCompilerDependencies());
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
ClassFileFactory factory = generationState.getFactory();
|
||||
if (jar != null) {
|
||||
try {
|
||||
CompileEnvironmentUtil.writeToJar(factory, new FileOutputStream(jar), mainClass, includeRuntime);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + jar, e);
|
||||
}
|
||||
}
|
||||
else if (outputDir != null) {
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(factory, outputDir);
|
||||
}
|
||||
else {
|
||||
throw new CompileEnvironmentException("Output directory or jar file is not specified - no files will be saved to the disk");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
finally {
|
||||
generationState.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean compileBunchOfSources(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
|
||||
configuration.getEnvironment().addSources(sourceFileOrDir);
|
||||
|
||||
return compileBunchOfSources(configuration, jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
public static boolean compileBunchOfSourceDirectories(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
|
||||
List<String> sources, String jar, String outputDir, boolean includeRuntime) {
|
||||
for (String source : sources) {
|
||||
configuration.getEnvironment().addSources(source);
|
||||
}
|
||||
|
||||
return compileBunchOfSources(configuration, jar, outputDir, includeRuntime);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ClassLoader compileText(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
String code) {
|
||||
configuration.getEnvironment()
|
||||
.addSources(new LightVirtualFile("script" + LocalTimeCounter.currentTime() + ".kt", JetLanguage.INSTANCE, code));
|
||||
|
||||
GenerationState generationState = analyzeAndGenerate(configuration);
|
||||
if (generationState == null) {
|
||||
return null;
|
||||
}
|
||||
return new GeneratedClassLoader(generationState.getFactory());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GenerationState analyzeAndGenerate(CompileEnvironmentConfiguration configuration) {
|
||||
return analyzeAndGenerate(configuration, configuration.getCompilerDependencies().getCompilerSpecialMode().isStubs());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GenerationState analyzeAndGenerate(
|
||||
CompileEnvironmentConfiguration configuration,
|
||||
boolean stubs
|
||||
) {
|
||||
AnalyzeExhaust exhaust = analyze(configuration, stubs);
|
||||
|
||||
if (exhaust == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
exhaust.throwIfError();
|
||||
|
||||
return generate(configuration, exhaust, stubs);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AnalyzeExhaust analyze(
|
||||
final CompileEnvironmentConfiguration configuration,
|
||||
boolean stubs) {
|
||||
final JetCoreEnvironment environment = configuration.getEnvironment();
|
||||
AnalyzerWithCompilerReport analyzerWithCompilerReport = new AnalyzerWithCompilerReport(configuration.getMessageCollector());
|
||||
final Predicate<PsiFile> filesToAnalyzeCompletely =
|
||||
stubs ? Predicates.<PsiFile>alwaysFalse() : Predicates.<PsiFile>alwaysTrue();
|
||||
analyzerWithCompilerReport.analyzeAndReport(
|
||||
new Function0<AnalyzeExhaust>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnalyzeExhaust invoke() {
|
||||
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
|
||||
JetControlFlowDataTraceFactory.EMPTY,
|
||||
configuration.getCompilerDependencies());
|
||||
}
|
||||
}, environment.getSourceFiles()
|
||||
);
|
||||
|
||||
return analyzerWithCompilerReport.hasErrors() ? null : analyzerWithCompilerReport.getAnalyzeExhaust();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static GenerationState generate(
|
||||
final CompileEnvironmentConfiguration configuration,
|
||||
AnalyzeExhaust exhaust,
|
||||
boolean stubs) {
|
||||
JetCoreEnvironment environment = configuration.getEnvironment();
|
||||
Project project = environment.getProject();
|
||||
Progress backendProgress = new Progress() {
|
||||
@Override
|
||||
public void log(String message) {
|
||||
configuration.getMessageCollector().report(CompilerMessageSeverity.LOGGING, message, CompilerMessageLocation.NO_LOCATION);
|
||||
}
|
||||
};
|
||||
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), backendProgress,
|
||||
exhaust, environment.getSourceFiles(),
|
||||
configuration.getCompilerDependencies().getCompilerSpecialMode());
|
||||
generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
|
||||
|
||||
List<CompilerPlugin> plugins = configuration.getCompilerPlugins();
|
||||
if (plugins != null) {
|
||||
CompilerPluginContext context = new CompilerPluginContext(project, exhaust.getBindingContext(), environment.getSourceFiles());
|
||||
for (CompilerPlugin plugin : plugins) {
|
||||
plugin.processFiles(context);
|
||||
}
|
||||
}
|
||||
return generationState;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class ModuleExecutionException extends RuntimeException {
|
||||
public ModuleExecutionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ModuleExecutionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ModuleExecutionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiErrorElement;
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
|
||||
import jet.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class AnalyzerWithCompilerReport {
|
||||
|
||||
@NotNull
|
||||
private static CompilerMessageSeverity convertSeverity(@NotNull Severity severity) {
|
||||
switch (severity) {
|
||||
case INFO:
|
||||
return CompilerMessageSeverity.INFO;
|
||||
case ERROR:
|
||||
return CompilerMessageSeverity.ERROR;
|
||||
case WARNING:
|
||||
return CompilerMessageSeverity.WARNING;
|
||||
}
|
||||
throw new IllegalStateException("Unknown severity: " + severity);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final SimpleDiagnosticFactory<PsiErrorElement> SYNTAX_ERROR_FACTORY = SimpleDiagnosticFactory.create(Severity.ERROR);
|
||||
|
||||
private boolean hasErrors = false;
|
||||
@NotNull
|
||||
private final MessageCollector messageCollectorWrapper;
|
||||
@Nullable
|
||||
private AnalyzeExhaust analyzeExhaust = null;
|
||||
|
||||
public AnalyzerWithCompilerReport(@NotNull final MessageCollector collector) {
|
||||
messageCollectorWrapper = new MessageCollector() {
|
||||
@Override
|
||||
public void report(@NotNull CompilerMessageSeverity severity,
|
||||
@NotNull String message,
|
||||
@NotNull CompilerMessageLocation location) {
|
||||
if (CompilerMessageSeverity.ERRORS.contains(severity)) {
|
||||
hasErrors = true;
|
||||
}
|
||||
collector.report(severity, message, location);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void reportDiagnostic(@NotNull Diagnostic diagnostic) {
|
||||
DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumn(diagnostic);
|
||||
VirtualFile virtualFile = diagnostic.getPsiFile().getVirtualFile();
|
||||
String path = virtualFile == null ? null : virtualFile.getPath();
|
||||
String render;
|
||||
if (diagnostic.getFactory() == SYNTAX_ERROR_FACTORY) {
|
||||
render = ((SyntaxErrorDiagnostic)diagnostic).message;
|
||||
}
|
||||
else {
|
||||
render = DefaultErrorMessages.RENDERER.render(diagnostic);
|
||||
}
|
||||
messageCollectorWrapper.report(convertSeverity(diagnostic.getSeverity()), render,
|
||||
CompilerMessageLocation.create(path, lineAndColumn.getLine(), lineAndColumn.getColumn()));
|
||||
}
|
||||
|
||||
private void reportIncompleteHierarchies() {
|
||||
assert analyzeExhaust != null;
|
||||
Collection<ClassDescriptor> incompletes = analyzeExhaust.getBindingContext().getKeys(BindingContext.INCOMPLETE_HIERARCHY);
|
||||
if (!incompletes.isEmpty()) {
|
||||
StringBuilder message = new StringBuilder("The following classes have incomplete hierarchies:\n");
|
||||
for (ClassDescriptor incomplete : incompletes) {
|
||||
String fqName = DescriptorUtils.getFQName(incomplete).getFqName();
|
||||
message.append(" ").append(fqName).append("\n");
|
||||
}
|
||||
messageCollectorWrapper.report(CompilerMessageSeverity.ERROR, message.toString(), CompilerMessageLocation.NO_LOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportDiagnostics() {
|
||||
assert analyzeExhaust != null;
|
||||
for (Diagnostic diagnostic : analyzeExhaust.getBindingContext().getDiagnostics()) {
|
||||
reportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportSyntaxErrors(@NotNull Collection<JetFile> files) {
|
||||
for (JetFile file : files) {
|
||||
file.accept(new PsiRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitErrorElement(PsiErrorElement element) {
|
||||
String description = element.getErrorDescription();
|
||||
String message = StringUtil.isEmpty(description) ? "Syntax error" : description;
|
||||
Diagnostic diagnostic = new SyntaxErrorDiagnostic(element, Severity.ERROR, message);
|
||||
reportDiagnostic(diagnostic);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AnalyzeExhaust getAnalyzeExhaust() {
|
||||
return analyzeExhaust;
|
||||
}
|
||||
|
||||
public boolean hasErrors() {
|
||||
return hasErrors;
|
||||
}
|
||||
|
||||
public void analyzeAndReport(@NotNull Function0<AnalyzeExhaust> analyzer, @NotNull Collection<JetFile> files) {
|
||||
reportSyntaxErrors(files);
|
||||
analyzeExhaust = analyzer.invoke();
|
||||
reportDiagnostics();
|
||||
reportIncompleteHierarchies();
|
||||
}
|
||||
|
||||
|
||||
public static class SyntaxErrorDiagnostic extends SimpleDiagnostic<PsiErrorElement> {
|
||||
private String message;
|
||||
|
||||
public SyntaxErrorDiagnostic(@NotNull PsiErrorElement psiElement, @NotNull Severity severity, String message) {
|
||||
super(psiElement, SYNTAX_ERROR_FACTORY, severity);
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CompilerMessageLocation {
|
||||
|
||||
public static final CompilerMessageLocation NO_LOCATION = new CompilerMessageLocation(null, -1, -1);
|
||||
|
||||
public static CompilerMessageLocation create(@Nullable String path, int line, int column) {
|
||||
if (path == null) {
|
||||
return NO_LOCATION;
|
||||
}
|
||||
return new CompilerMessageLocation(path, line, column);
|
||||
}
|
||||
|
||||
private final String path;
|
||||
private final int line;
|
||||
private final int column;
|
||||
|
||||
private CompilerMessageLocation(@Nullable String path, int line, int column) {
|
||||
this.path = path;
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public enum CompilerMessageSeverity {
|
||||
INFO,
|
||||
ERROR,
|
||||
WARNING,
|
||||
EXCEPTION,
|
||||
LOGGING;
|
||||
|
||||
public static final EnumSet<CompilerMessageSeverity> ERRORS = EnumSet.of(ERROR, EXCEPTION);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface MessageCollector {
|
||||
MessageCollector PLAIN_TEXT_TO_SYSTEM_ERR = new MessageCollector() {
|
||||
@Override
|
||||
public void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
|
||||
System.err.println(MessageRenderer.PLAIN.render(severity, message, location));
|
||||
}
|
||||
};
|
||||
|
||||
void report(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location);
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface MessageRenderer {
|
||||
|
||||
MessageRenderer TAGS = new MessageRenderer() {
|
||||
@Override
|
||||
public String renderPreamble() {
|
||||
return "<MESSAGES>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
out.append("<").append(severity.toString());
|
||||
if (location.getPath() != null) {
|
||||
out.append(" path=\"").append(e(location.getPath())).append("\"");
|
||||
out.append(" line=\"").append(location.getLine()).append("\"");
|
||||
out.append(" column=\"").append(location.getColumn()).append("\"");
|
||||
}
|
||||
out.append(">\n");
|
||||
|
||||
out.append(e(message));
|
||||
|
||||
out.append("</").append(severity.toString()).append(">\n");
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private String e(String str) {
|
||||
return StringUtil.escapeXml(str);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderException(@NotNull Throwable e) {
|
||||
return render(CompilerMessageSeverity.EXCEPTION, PLAIN.renderException(e), CompilerMessageLocation.NO_LOCATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderConclusion() {
|
||||
return "</MESSAGES>";
|
||||
}
|
||||
};
|
||||
|
||||
MessageRenderer PLAIN = new MessageRenderer() {
|
||||
@Override
|
||||
public String renderPreamble() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
|
||||
String path = location.getPath();
|
||||
String position = path == null ? "" : path + ": (" + (location.getLine() + ", " + location.getColumn()) + ") ";
|
||||
return severity + ": " + position + message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderException(@NotNull Throwable e) {
|
||||
StringWriter out = new StringWriter();
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
e.printStackTrace(new PrintWriter(out));
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String renderConclusion() {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
String renderPreamble();
|
||||
String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location);
|
||||
String renderException(@NotNull Throwable e);
|
||||
String renderConclusion();
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.messages;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class MessageUtil {
|
||||
public static CompilerMessageLocation psiElementToMessageLocation(PsiElement element) {
|
||||
PsiFile file = element.getContainingFile();
|
||||
DiagnosticUtils.LineAndColumn lineAndColumn = DiagnosticUtils.getLineAndColumnInPsiFile(file, element.getTextRange());
|
||||
return CompilerMessageLocation.create(file.getVirtualFile().getPath(), lineAndColumn.getLine(), lineAndColumn.getColumn());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
OUT Usage: org.jetbrains.jet.cli.CompilerArguments
|
||||
OUT Usage: org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments
|
||||
OUT -output [String] output directory
|
||||
OUT -jar [String] jar file name
|
||||
OUT -src [String] source file or directory
|
||||
|
||||
@@ -84,7 +84,7 @@ public abstract class KotlinIntegrationTestBase {
|
||||
Collection<String> javaArgs = new ArrayList<String>();
|
||||
javaArgs.add("-cp");
|
||||
javaArgs.add(classpath);
|
||||
javaArgs.add("org.jetbrains.jet.cli.KotlinCompiler");
|
||||
javaArgs.add("org.jetbrains.jet.cli.jvm.K2JVMCompiler");
|
||||
Collections.addAll(javaArgs, arguments);
|
||||
|
||||
return runJava(logName, ArrayUtil.toStringArray(javaArgs));
|
||||
|
||||
@@ -30,9 +30,8 @@ import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.testFramework.TestDataFile;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.jet.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
|
||||
import org.jetbrains.jet.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentConfiguration;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentUtil;
|
||||
import org.jetbrains.jet.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.compiler.KotlinToJVMBytecodeCompiler;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
|
||||
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentConfiguration;
|
||||
import org.jetbrains.jet.compiler.KotlinToJVMBytecodeCompiler;
|
||||
import org.jetbrains.jet.compiler.messages.MessageCollector;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
|
||||
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
package org.jetbrains.jet.codegen.forTestCompile;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -37,9 +38,9 @@ public class ForTestCompileBuiltins {
|
||||
|
||||
@Override
|
||||
protected void doCompile(@NotNull File classesDir) throws Exception {
|
||||
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(
|
||||
ExitCode exitCode = new K2JVMCompiler().exec(
|
||||
System.err, "-output", classesDir.getPath(), "-src", "./compiler/frontend/src", "-mode", "builtins");
|
||||
if (exitCode != KotlinCompiler.ExitCode.OK) {
|
||||
if (exitCode != ExitCode.OK) {
|
||||
throw new IllegalStateException("jdk headers compilation failed: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -17,7 +17,8 @@
|
||||
package org.jetbrains.jet.codegen.forTestCompile;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -37,9 +38,9 @@ public class ForTestCompileJdkHeaders {
|
||||
|
||||
@Override
|
||||
protected void doCompile(@NotNull File classesDir) throws Exception {
|
||||
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(
|
||||
ExitCode exitCode = new K2JVMCompiler().exec(
|
||||
System.err, "-output", classesDir.getPath(), "-src", "./jdk-headers/src", "-mode", "jdkHeaders");
|
||||
if (exitCode != KotlinCompiler.ExitCode.OK) {
|
||||
if (exitCode != ExitCode.OK) {
|
||||
throw new IllegalStateException("jdk headers compilation failed: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,10 @@
|
||||
|
||||
package org.jetbrains.jet.codegen.forTestCompile;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
@@ -29,12 +27,9 @@ import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
/**
|
||||
* Compile stdlib.jar that can be used in tests
|
||||
@@ -63,12 +58,12 @@ public class ForTestCompileRuntime {
|
||||
}
|
||||
|
||||
private static void compileStdlib(File destdir) throws IOException {
|
||||
KotlinCompiler.ExitCode exitCode = new KotlinCompiler().exec(System.err,
|
||||
ExitCode exitCode = new K2JVMCompiler().exec(System.err,
|
||||
"-output", destdir.getPath(),
|
||||
"-src", "./libraries/stdlib/src",
|
||||
"-mode", "stdlib",
|
||||
"-classpath", "out/production/runtime");
|
||||
if (exitCode != KotlinCompiler.ExitCode.OK) {
|
||||
if (exitCode != ExitCode.OK) {
|
||||
throw new IllegalStateException("stdlib for test compilation failed: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileJdkHeaders;
|
||||
import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author alex.tkachman
|
||||
*/
|
||||
public class CompileEnvironmentTest extends TestCase {
|
||||
|
||||
public void testSmokeWithCompilerJar() throws IOException {
|
||||
File tempDir = FileUtil.createTempDirectory("compilerTest", "compilerTest");
|
||||
|
||||
try {
|
||||
File stdlib = ForTestCompileRuntime.runtimeJarForTests();
|
||||
File jdkHeaders = ForTestCompileJdkHeaders.jdkHeadersForTests();
|
||||
File resultJar = new File(tempDir, "result.jar");
|
||||
KotlinCompiler.ExitCode rv = new KotlinCompiler().exec(System.out,
|
||||
"-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts",
|
||||
"-jar", resultJar.getAbsolutePath(),
|
||||
"-stdlib", stdlib.getAbsolutePath(),
|
||||
"-jdkHeaders", jdkHeaders.getAbsolutePath());
|
||||
Assert.assertEquals("compilation completed with non-zero code", KotlinCompiler.ExitCode.OK, rv);
|
||||
FileInputStream fileInputStream = new FileInputStream(resultJar);
|
||||
try {
|
||||
JarInputStream is = new JarInputStream(fileInputStream);
|
||||
try {
|
||||
final List<String> entries = listEntries(is);
|
||||
assertTrue(entries.contains("Smoke/namespace.class"));
|
||||
assertEquals(1, entries.size());
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
fileInputStream.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
FileUtil.delete(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
public void testSmokeWithCompilerOutput() throws IOException {
|
||||
File tempDir = FileUtil.createTempDirectory("compilerTest", "compilerTest");
|
||||
try {
|
||||
File out = new File(tempDir, "out");
|
||||
File stdlib = ForTestCompileRuntime.runtimeJarForTests();
|
||||
File jdkHeaders = ForTestCompileJdkHeaders.jdkHeadersForTests();
|
||||
KotlinCompiler.ExitCode exitCode = new KotlinCompiler()
|
||||
.exec(System.out, "-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt", "-output",
|
||||
out.getAbsolutePath(), "-stdlib", stdlib.getAbsolutePath(), "-jdkHeaders", jdkHeaders.getAbsolutePath());
|
||||
Assert.assertEquals(KotlinCompiler.ExitCode.OK, exitCode);
|
||||
assertEquals(1, out.listFiles().length);
|
||||
assertEquals(1, out.listFiles()[0].listFiles().length);
|
||||
} finally {
|
||||
FileUtil.delete(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> listEntries(JarInputStream is) throws IOException {
|
||||
List<String> entries = new ArrayList<String>();
|
||||
while (true) {
|
||||
final JarEntry jarEntry = is.getNextJarEntry();
|
||||
if (jarEntry == null) {
|
||||
break;
|
||||
}
|
||||
entries.add(jarEntry.getName());
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*
|
||||
* @see WriteSignatureTest
|
||||
*/
|
||||
public class CompileJavaAgainstKotlinTest extends TestCaseWithTmpdir {
|
||||
|
||||
private final File ktFile;
|
||||
private final File javaFile;
|
||||
private JetCoreEnvironment jetCoreEnvironment;
|
||||
|
||||
public CompileJavaAgainstKotlinTest(File ktFile) {
|
||||
this.ktFile = ktFile;
|
||||
Assert.assertTrue(ktFile.getName().endsWith(".kt"));
|
||||
this.javaFile = new File(ktFile.getPath().replaceFirst("\\.kt", ".java"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ktFile.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||
|
||||
|
||||
String text = FileUtil.loadFile(ktFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
|
||||
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
|
||||
|
||||
Disposer.dispose(myTestRootDisposable);
|
||||
|
||||
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
|
||||
try {
|
||||
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile));
|
||||
List<String> options = Arrays.asList(
|
||||
"-classpath", tmpdir.getPath() + System.getProperty("path.separator") + "out/production/stdlib",
|
||||
"-d", tmpdir.getPath()
|
||||
);
|
||||
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
|
||||
|
||||
Assert.assertTrue(task.call());
|
||||
} finally {
|
||||
fileManager.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/compileJavaAgainstKotlin", true, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new CompileJavaAgainstKotlinTest(file);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir {
|
||||
|
||||
private final File ktAFile;
|
||||
private final File ktBFile;
|
||||
|
||||
public CompileKotlinAgainstKotlinTest(File ktAFile) {
|
||||
Assert.assertTrue(ktAFile.getName().endsWith("A.kt"));
|
||||
this.ktAFile = ktAFile;
|
||||
this.ktBFile = new File(ktAFile.getPath().replaceFirst("A\\.kt$", "B.kt"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ktAFile.getName();
|
||||
}
|
||||
|
||||
private File aDir;
|
||||
private File bDir;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
aDir = new File(tmpdir, "a");
|
||||
bDir = new File(tmpdir, "b");
|
||||
JetTestUtils.mkdirs(aDir);
|
||||
JetTestUtils.mkdirs(bDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
compileA();
|
||||
compileB();
|
||||
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{ aDir.toURI().toURL(), bDir.toURI().toURL() });
|
||||
Class<?> clazz = classLoader.loadClass("bbb.namespace");
|
||||
Method main = clazz.getMethod("main", new Class[] { String[].class });
|
||||
main.invoke(null, new Object[] { new String[0] });
|
||||
}
|
||||
|
||||
private void compileA() throws IOException {
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||
|
||||
String text = FileUtil.loadFile(ktAFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(ktAFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
|
||||
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, aDir.getPath());
|
||||
|
||||
Disposer.dispose(myTestRootDisposable);
|
||||
}
|
||||
|
||||
private void compileB() throws IOException {
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||
|
||||
jetCoreEnvironment.addToClasspath(aDir);
|
||||
|
||||
String text = FileUtil.loadFile(ktBFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(ktAFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
|
||||
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, bDir.getPath());
|
||||
|
||||
Disposer.dispose(myTestRootDisposable);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
class Filter implements FilenameFilter {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith("A.kt");
|
||||
}
|
||||
}
|
||||
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/compileKotlinAgainstKotlin", true, new Filter(), new JetTestCaseBuilder.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new CompileKotlinAgainstKotlinTest(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
* @see ReadJavaBinaryClassTest
|
||||
*/
|
||||
public class JavaDescriptorResolverTest extends TestCaseWithTmpdir {
|
||||
|
||||
// This test can be implemented in ReadJavaBinaryClass test, but it is simpler here
|
||||
public void testInner() throws Exception {
|
||||
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
|
||||
try {
|
||||
File file = new File("compiler/testData/javaDescriptorResolver/inner.java");
|
||||
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(file));
|
||||
List<String> options = Arrays.asList(
|
||||
"-d", tmpdir.getPath()
|
||||
);
|
||||
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
|
||||
|
||||
Assert.assertTrue(task.call());
|
||||
} finally {
|
||||
fileManager.close();
|
||||
}
|
||||
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
jetCoreEnvironment.addToClasspath(tmpdir);
|
||||
|
||||
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
|
||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
|
||||
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName("A"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||
Assert.assertNotNull(classDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,568 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.PropertyCodegen;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
class NamespaceComparator {
|
||||
|
||||
private final boolean includeObject;
|
||||
|
||||
private NamespaceComparator(boolean includeObject) {
|
||||
this.includeObject = includeObject;
|
||||
}
|
||||
|
||||
public static void compareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb, boolean includeObject,
|
||||
@NotNull File txtFile) {
|
||||
String serialized = new NamespaceComparator(includeObject).doCompareNamespaces(nsa, nsb);
|
||||
try {
|
||||
for (;;) {
|
||||
String expected = Files.toString(txtFile, Charset.forName("utf-8")).replace("\r\n", "\n");
|
||||
|
||||
if (expected.contains("kick me")) {
|
||||
// for developer
|
||||
System.err.println("generating " + txtFile);
|
||||
Files.write(serialized, txtFile, Charset.forName("utf-8"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// compare with hardcopy: make sure nothing is lost in output
|
||||
Assert.assertEquals(expected, serialized);
|
||||
break;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String doCompareNamespaces(@NotNull NamespaceDescriptor nsa, @NotNull NamespaceDescriptor nsb) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Assert.assertEquals(nsa.getName(), nsb.getName());
|
||||
|
||||
sb.append("namespace " + nsa.getName() + "\n\n");
|
||||
|
||||
Assert.assertTrue(!nsa.getMemberScope().getAllDescriptors().isEmpty());
|
||||
|
||||
Set<String> classifierNames = new HashSet<String>();
|
||||
Set<String> propertyNames = new HashSet<String>();
|
||||
Set<String> functionNames = new HashSet<String>();
|
||||
|
||||
for (DeclarationDescriptor ad : nsa.getMemberScope().getAllDescriptors()) {
|
||||
if (ad instanceof ClassifierDescriptor) {
|
||||
classifierNames.add(ad.getName());
|
||||
}
|
||||
else if (ad instanceof PropertyDescriptor) {
|
||||
propertyNames.add(ad.getName());
|
||||
}
|
||||
else if (ad instanceof FunctionDescriptor) {
|
||||
functionNames.add(ad.getName());
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("unknown member: " + ad);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : classifierNames) {
|
||||
ClassifierDescriptor ca = nsa.getMemberScope().getClassifier(name);
|
||||
ClassifierDescriptor cb = nsb.getMemberScope().getClassifier(name);
|
||||
Assert.assertTrue(ca != null);
|
||||
Assert.assertTrue(cb != null);
|
||||
compareClassifiers(ca, cb, sb);
|
||||
}
|
||||
|
||||
for (String name : propertyNames) {
|
||||
Set<VariableDescriptor> pa = nsa.getMemberScope().getProperties(name);
|
||||
Set<VariableDescriptor> pb = nsb.getMemberScope().getProperties(name);
|
||||
compareDeclarationSets(pa, pb, sb);
|
||||
|
||||
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.getterName(name)).isEmpty());
|
||||
Assert.assertTrue(nsb.getMemberScope().getFunctions(PropertyCodegen.setterName(name)).isEmpty());
|
||||
}
|
||||
|
||||
for (String name : functionNames) {
|
||||
Set<FunctionDescriptor> fa = nsa.getMemberScope().getFunctions(name);
|
||||
Set<FunctionDescriptor> fb = nsb.getMemberScope().getFunctions(name);
|
||||
compareDeclarationSets(fa, fb, sb);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static void compareDeclarationSets(Set<? extends DeclarationDescriptor> a, Set<? extends DeclarationDescriptor> b,
|
||||
@NotNull StringBuilder sb) {
|
||||
String at = serializedDeclarationSets(a);
|
||||
String bt = serializedDeclarationSets(b);
|
||||
Assert.assertEquals(at, bt);
|
||||
sb.append(at);
|
||||
}
|
||||
|
||||
private static String serializedDeclarationSets(Collection<? extends DeclarationDescriptor> ds) {
|
||||
List<String> strings = new ArrayList<String>();
|
||||
for (DeclarationDescriptor d : ds) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
new Serializer(sb).serialize(d);
|
||||
strings.add(sb.toString());
|
||||
}
|
||||
|
||||
Collections.sort(strings, new MemberComparator());
|
||||
|
||||
StringBuilder r = new StringBuilder();
|
||||
for (String string : strings) {
|
||||
r.append(string);
|
||||
r.append("\n");
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This comparator only affects test output, you can drop it if you don't want to understand it.
|
||||
*/
|
||||
private static class MemberComparator implements Comparator<String> {
|
||||
|
||||
@NotNull
|
||||
private String normalize(String s) {
|
||||
return s.replaceFirst(
|
||||
"^ *(private|final|abstract|open|override|fun|val|var|/\\*.*?\\*/|((?!<init>)<.*?>)| )*",
|
||||
"")
|
||||
+ s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(@NotNull String a, @NotNull String b) {
|
||||
return normalize(a).compareTo(normalize(b));
|
||||
}
|
||||
}
|
||||
|
||||
private void compareClassifiers(@NotNull ClassifierDescriptor a, @NotNull ClassifierDescriptor b, @NotNull StringBuilder sb) {
|
||||
StringBuilder sba = new StringBuilder();
|
||||
StringBuilder sbb = new StringBuilder();
|
||||
|
||||
new FullContentSerialier(sba).serialize((ClassDescriptor) a);
|
||||
new FullContentSerialier(sbb).serialize((ClassDescriptor) b);
|
||||
|
||||
String as = sba.toString();
|
||||
String bs = sbb.toString();
|
||||
|
||||
Assert.assertEquals(as, bs);
|
||||
sb.append(as);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class Serializer {
|
||||
|
||||
protected final StringBuilder sb;
|
||||
|
||||
public Serializer(StringBuilder sb) {
|
||||
this.sb = sb;
|
||||
}
|
||||
|
||||
public void serialize(ClassKind kind) {
|
||||
switch (kind) {
|
||||
case CLASS:
|
||||
sb.append("class");
|
||||
break;
|
||||
case TRAIT:
|
||||
sb.append("trait");
|
||||
break;
|
||||
case OBJECT:
|
||||
sb.append("object");
|
||||
break;
|
||||
case ANNOTATION_CLASS:
|
||||
sb.append("annotation class");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unknown class kind: " + kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Object invoke(Method method, Object thiz, Object... args) {
|
||||
try {
|
||||
return method.invoke(thiz, args);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("failed to invoke " + method + ": " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void serialize(FunctionDescriptor fun) {
|
||||
serialize(fun.getModality());
|
||||
sb.append(" ");
|
||||
|
||||
if (!fun.getAnnotations().isEmpty()) {
|
||||
new Serializer(sb).serializeSeparated(fun.getAnnotations(), " ");
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
if (!fun.getOverriddenDescriptors().isEmpty()) {
|
||||
sb.append("override /*" + fun.getOverriddenDescriptors().size() + "*/ ");
|
||||
}
|
||||
|
||||
if (fun instanceof ConstructorDescriptor) {
|
||||
sb.append("/*constructor*/ ");
|
||||
}
|
||||
sb.append("fun ");
|
||||
if (!fun.getTypeParameters().isEmpty()) {
|
||||
sb.append("<");
|
||||
new Serializer(sb).serializeCommaSeparated(fun.getTypeParameters());
|
||||
sb.append(">");
|
||||
}
|
||||
|
||||
if (fun.getReceiverParameter().exists()) {
|
||||
new TypeSerializer(sb).serialize(fun.getReceiverParameter());
|
||||
sb.append(".");
|
||||
}
|
||||
|
||||
sb.append(fun.getName());
|
||||
sb.append("(");
|
||||
new TypeSerializer(sb).serializeCommaSeparated(fun.getValueParameters());
|
||||
sb.append("): ");
|
||||
new TypeSerializer(sb).serialize(fun.getReturnType());
|
||||
}
|
||||
|
||||
public void serialize(ExtensionReceiver extensionReceiver) {
|
||||
serialize(extensionReceiver.getType());
|
||||
}
|
||||
|
||||
public void serialize(PropertyDescriptor prop) {
|
||||
serialize(prop.getModality());
|
||||
sb.append(" ");
|
||||
|
||||
if (!prop.getAnnotations().isEmpty()) {
|
||||
new Serializer(sb).serializeSeparated(prop.getAnnotations(), " ");
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
if (prop.isVar()) {
|
||||
sb.append("var ");
|
||||
}
|
||||
else {
|
||||
sb.append("val ");
|
||||
}
|
||||
if (!prop.getTypeParameters().isEmpty()) {
|
||||
sb.append(" <");
|
||||
new Serializer(sb).serializeCommaSeparated(prop.getTypeParameters());
|
||||
sb.append("> ");
|
||||
}
|
||||
if (prop.getReceiverParameter().exists()) {
|
||||
new TypeSerializer(sb).serialize(prop.getReceiverParameter().getType());
|
||||
sb.append(".");
|
||||
}
|
||||
sb.append(prop.getName());
|
||||
sb.append(": ");
|
||||
new TypeSerializer(sb).serialize(prop.getType());
|
||||
}
|
||||
|
||||
public void serialize(ValueParameterDescriptor valueParameter) {
|
||||
sb.append("/*");
|
||||
sb.append(valueParameter.getIndex());
|
||||
sb.append("*/ ");
|
||||
if (valueParameter.getVarargElementType() != null) {
|
||||
sb.append("vararg ");
|
||||
}
|
||||
sb.append(valueParameter.getName());
|
||||
sb.append(": ");
|
||||
if (valueParameter.getVarargElementType() != null) {
|
||||
new TypeSerializer(sb).serialize(valueParameter.getVarargElementType());
|
||||
}
|
||||
else {
|
||||
new TypeSerializer(sb).serialize(valueParameter.getType());
|
||||
}
|
||||
if (valueParameter.hasDefaultValue()) {
|
||||
sb.append(" = ?");
|
||||
}
|
||||
}
|
||||
|
||||
public void serialize(Variance variance) {
|
||||
if (variance == Variance.INVARIANT) {
|
||||
|
||||
}
|
||||
else {
|
||||
sb.append(variance);
|
||||
sb.append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
public void serialize(Modality modality) {
|
||||
sb.append(modality.name().toLowerCase());
|
||||
}
|
||||
|
||||
public void serialize(AnnotationDescriptor annotation) {
|
||||
new TypeSerializer(sb).serialize(annotation.getType());
|
||||
sb.append("(");
|
||||
serializeCommaSeparated(annotation.getValueArguments());
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
public void serializeCommaSeparated(List<?> list) {
|
||||
serializeSeparated(list, ", ");
|
||||
}
|
||||
|
||||
public void serializeSeparated(List<?> list, String sep) {
|
||||
boolean first = true;
|
||||
for (Object o : list) {
|
||||
if (!first) {
|
||||
sb.append(sep);
|
||||
}
|
||||
serialize(o);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
private Method getMethodToSerialize(Object o) {
|
||||
if (o == null) {
|
||||
throw new IllegalStateException("won't serialize null");
|
||||
}
|
||||
|
||||
// TODO: cache
|
||||
for (Method method : this.getClass().getMethods()) {
|
||||
if (!method.getName().equals("serialize")) {
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes().length != 1) {
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes()[0].equals(Object.class)) {
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes()[0].isInstance(o)) {
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("don't know how to serialize " + o + " (of " + o.getClass() + ")");
|
||||
}
|
||||
|
||||
public void serialize(Object o) {
|
||||
Method method = getMethodToSerialize(o);
|
||||
invoke(method, this, o);
|
||||
}
|
||||
|
||||
public void serialize(String s) {
|
||||
sb.append(s);
|
||||
}
|
||||
|
||||
public void serialize(ClassDescriptor clazz) {
|
||||
sb.append(DescriptorUtils.getFQName(clazz));
|
||||
}
|
||||
|
||||
public void serialize(NamespaceDescriptor ns) {
|
||||
sb.append(DescriptorUtils.getFQName(ns));
|
||||
}
|
||||
|
||||
public void serialize(TypeParameterDescriptor param) {
|
||||
sb.append("/*");
|
||||
sb.append(param.getIndex());
|
||||
if (param.isReified()) {
|
||||
sb.append(",r");
|
||||
}
|
||||
sb.append("*/ ");
|
||||
serialize(param.getVariance());
|
||||
sb.append(param.getName());
|
||||
if (!param.getUpperBounds().isEmpty()) {
|
||||
sb.append(" : ");
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (JetType upper : param.getUpperBounds()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
new TypeSerializer(sb).serialize(upper);
|
||||
list.add(sb.toString());
|
||||
}
|
||||
Collections.sort(list);
|
||||
serializeSeparated(list, " & "); // TODO: use where
|
||||
}
|
||||
// TODO: lower bounds
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TypeSerializer extends Serializer {
|
||||
|
||||
public TypeSerializer(StringBuilder sb) {
|
||||
super(sb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(TypeParameterDescriptor param) {
|
||||
sb.append(param.getName());
|
||||
}
|
||||
|
||||
public void serialize(@NotNull JetType type) {
|
||||
serialize(type.getConstructor().getDeclarationDescriptor());
|
||||
if (!type.getArguments().isEmpty()) {
|
||||
sb.append("<");
|
||||
boolean first = true;
|
||||
for (TypeProjection proj : type.getArguments()) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
}
|
||||
serialize(proj.getProjectionKind());
|
||||
serialize(proj.getType());
|
||||
first = false;
|
||||
}
|
||||
sb.append(">");
|
||||
}
|
||||
if (type.isNullable()) {
|
||||
sb.append("?");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isRootNs(DeclarationDescriptor ns) {
|
||||
return ns instanceof NamespaceDescriptor && ns.getContainingDeclaration() instanceof ModuleDescriptor;
|
||||
}
|
||||
|
||||
private static class NamespacePrefixSerializer extends Serializer {
|
||||
|
||||
public NamespacePrefixSerializer(StringBuilder sb) {
|
||||
super(sb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(NamespaceDescriptor ns) {
|
||||
super.serialize(ns);
|
||||
if (isRootNs(ns)) {
|
||||
return;
|
||||
}
|
||||
sb.append(".");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(ClassDescriptor clazz) {
|
||||
super.serialize(clazz);
|
||||
sb.append(".");
|
||||
}
|
||||
}
|
||||
|
||||
private class FullContentSerialier extends Serializer {
|
||||
private FullContentSerialier(StringBuilder sb) {
|
||||
super(sb);
|
||||
}
|
||||
|
||||
public void serialize(ClassDescriptor klass) {
|
||||
|
||||
if (!klass.getAnnotations().isEmpty()) {
|
||||
new Serializer(sb).serializeSeparated(klass.getAnnotations(), " ");
|
||||
sb.append(" ");
|
||||
}
|
||||
serialize(klass.getModality());
|
||||
sb.append(" ");
|
||||
|
||||
serialize(klass.getKind());
|
||||
sb.append(" ");
|
||||
|
||||
new Serializer(sb).serialize(klass);
|
||||
|
||||
if (!klass.getTypeConstructor().getParameters().isEmpty()) {
|
||||
sb.append("<");
|
||||
serializeCommaSeparated(klass.getTypeConstructor().getParameters());
|
||||
sb.append(">");
|
||||
}
|
||||
|
||||
if (!klass.getTypeConstructor().getSupertypes().isEmpty()) {
|
||||
sb.append(" : ");
|
||||
new TypeSerializer(sb).serializeCommaSeparated(new ArrayList<JetType>(klass.getTypeConstructor().getSupertypes()));
|
||||
}
|
||||
|
||||
sb.append(" {\n");
|
||||
|
||||
List<TypeProjection> typeArguments = new ArrayList<TypeProjection>();
|
||||
for (TypeParameterDescriptor param : klass.getTypeConstructor().getParameters()) {
|
||||
typeArguments.add(new TypeProjection(Variance.INVARIANT, param.getDefaultType()));
|
||||
}
|
||||
|
||||
List<String> memberStrings = new ArrayList<String>();
|
||||
|
||||
for (ConstructorDescriptor constructor : klass.getConstructors()) {
|
||||
StringBuilder constructorSb = new StringBuilder();
|
||||
new Serializer(constructorSb).serialize(constructor);
|
||||
memberStrings.add(constructorSb.toString());
|
||||
}
|
||||
|
||||
JetScope memberScope = klass.getMemberScope(typeArguments);
|
||||
for (DeclarationDescriptor member : memberScope.getAllDescriptors()) {
|
||||
if (!includeObject) {
|
||||
if (member.getName().matches("equals|hashCode|finalize|wait|notify(All)?|toString|clone|getClass")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
StringBuilder memberSb = new StringBuilder();
|
||||
new FullContentSerialier(memberSb).serialize(member);
|
||||
memberStrings.add(memberSb.toString());
|
||||
}
|
||||
|
||||
Collections.sort(memberStrings, new MemberComparator());
|
||||
|
||||
for (String memberString : memberStrings) {
|
||||
sb.append(indent(memberString));
|
||||
}
|
||||
|
||||
if (klass.getClassObjectDescriptor() != null) {
|
||||
StringBuilder sbForClassObject = new StringBuilder();
|
||||
new FullContentSerialier(sbForClassObject).serialize(klass.getClassObjectDescriptor());
|
||||
sb.append(indent(sbForClassObject.toString()));
|
||||
}
|
||||
|
||||
sb.append("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String indent(String string) {
|
||||
try {
|
||||
StringBuilder r = new StringBuilder();
|
||||
BufferedReader reader = new BufferedReader(new StringReader(string));
|
||||
for (;;) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
r.append(" ");
|
||||
r.append(line);
|
||||
r.append("\n");
|
||||
}
|
||||
return r.toString();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.junit.Assert;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.ToolProvider;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir {
|
||||
|
||||
private final File ktFile;
|
||||
private final File javaFile;
|
||||
private final File txtFile;
|
||||
|
||||
public ReadJavaBinaryClassTest(File ktFile) {
|
||||
this.ktFile = ktFile;
|
||||
Assert.assertTrue(ktFile.getName().endsWith(".kt"));
|
||||
this.javaFile = new File(ktFile.getPath().replaceFirst("\\.kt$", ".java"));
|
||||
this.txtFile = new File(ktFile.getPath().replaceFirst("\\.kt$", ".txt"));
|
||||
setName(javaFile.getName());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
NamespaceDescriptor nsa = compileKotlin();
|
||||
NamespaceDescriptor nsb = compileJava();
|
||||
NamespaceComparator.compareNamespaces(nsa, nsb, false, txtFile);
|
||||
}
|
||||
|
||||
private NamespaceDescriptor compileKotlin() throws Exception {
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
String text = FileUtil.loadFile(ktFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
|
||||
psiFile, JetControlFlowDataTraceFactory.EMPTY,
|
||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true))
|
||||
.getBindingContext();
|
||||
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel("test"));
|
||||
}
|
||||
|
||||
private NamespaceDescriptor compileJava() throws Exception {
|
||||
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
|
||||
|
||||
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, Locale.ENGLISH, Charset.forName("utf-8"));
|
||||
try {
|
||||
Iterable<? extends JavaFileObject> javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile));
|
||||
List<String> options = Arrays.asList(
|
||||
"-classpath", "out/production/runtime" + File.pathSeparator + JetTestUtils.getAnnotationsJar().getPath(),
|
||||
"-d", tmpdir.getPath()
|
||||
);
|
||||
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);
|
||||
|
||||
Assert.assertTrue(task.call());
|
||||
} finally {
|
||||
fileManager.close();
|
||||
}
|
||||
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
jetCoreEnvironment.addToClasspath(tmpdir);
|
||||
jetCoreEnvironment.addToClasspath(new File("out/production/runtime"));
|
||||
|
||||
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
|
||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
|
||||
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||
return javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readJavaBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new ReadJavaBinaryClassTest(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.codegen.GenerationUtils;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Compile Kotlin and then parse model from .class files.
|
||||
*
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir {
|
||||
|
||||
private JetCoreEnvironment jetCoreEnvironment;
|
||||
|
||||
private final File testFile;
|
||||
private final File txtFile;
|
||||
|
||||
public ReadKotlinBinaryClassTest(@NotNull File testFile) {
|
||||
this.testFile = testFile;
|
||||
this.txtFile = new File(testFile.getPath().replaceFirst("\\.kt$", ".txt"));
|
||||
setName(testFile.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
String text = FileUtil.loadFile(testFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(testFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
GenerationState state = GenerationUtils.compileFileGetGenerationStateForTest(psiFile, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
ClassFileFactory classFileFactory = state.getFactory();
|
||||
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
|
||||
|
||||
NamespaceDescriptor namespaceFromSource = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, psiFile);
|
||||
|
||||
Assert.assertEquals("test", namespaceFromSource.getName());
|
||||
|
||||
Disposer.dispose(myTestRootDisposable);
|
||||
|
||||
|
||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
|
||||
|
||||
jetCoreEnvironment.addToClasspath(tmpdir);
|
||||
jetCoreEnvironment.addToClasspath(new File("out/production/runtime"));
|
||||
|
||||
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
|
||||
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.JDK_HEADERS, true), jetCoreEnvironment.getProject());
|
||||
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
|
||||
NamespaceDescriptor namespaceFromClass = javaDescriptorResolver.resolveNamespace(FqName.topLevel("test"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||
|
||||
NamespaceComparator.compareNamespaces(namespaceFromSource, namespaceFromClass, false, txtFile);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/readKotlinBinaryClass", true, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new ReadKotlinBinaryClassTest(file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public abstract class TestCaseWithTmpdir extends UsefulTestCase {
|
||||
|
||||
protected File tmpdir;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
tmpdir = JetTestUtils.tmpDirForTest(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler;
|
||||
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.common.io.Files;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import org.junit.Assert;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.commons.EmptyVisitor;
|
||||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Test correctness of written JVM signature
|
||||
*
|
||||
* @author Stepan Koltsov
|
||||
*
|
||||
* @see CompileJavaAgainstKotlinTest
|
||||
*/
|
||||
public class WriteSignatureTest extends TestCaseWithTmpdir {
|
||||
|
||||
private final File ktFile;
|
||||
private JetCoreEnvironment jetCoreEnvironment;
|
||||
|
||||
public WriteSignatureTest(File ktFile) {
|
||||
this.ktFile = ktFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ktFile.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(myTestRootDisposable);
|
||||
|
||||
|
||||
String text = FileUtil.loadFile(ktFile);
|
||||
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(ktFile.getName(), JetLanguage.INSTANCE, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
|
||||
|
||||
ClassFileFactory classFileFactory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile, CompilerSpecialMode.REGULAR);
|
||||
|
||||
CompileEnvironmentUtil.writeToOutputDirectory(classFileFactory, tmpdir.getPath());
|
||||
|
||||
Disposer.dispose(myTestRootDisposable);
|
||||
|
||||
final Expectation expectation = parseExpectations();
|
||||
|
||||
ActualSignature actualSignature = readSignature(expectation.className, expectation.methodName);
|
||||
|
||||
String template =
|
||||
"jvm signature: %s\n" +
|
||||
"generic signature: %s\n" +
|
||||
"kotlin signature: %s\n" +
|
||||
"";
|
||||
|
||||
String expected = String.format(template, expectation.jvmSignature, expectation.genericSignature, expectation.kotlinSignature);
|
||||
String actual = String.format(template, actualSignature.jvmSignature, actualSignature.genericSignature, actualSignature.kotlinSignature);
|
||||
|
||||
Assert.assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
private static class ActualSignature {
|
||||
private final String jvmSignature;
|
||||
private final String genericSignature;
|
||||
private final String kotlinSignature;
|
||||
|
||||
private ActualSignature(@NotNull String jvmSignature, @Nullable String genericSignature, @Nullable String kotlinSignature) {
|
||||
this.jvmSignature = jvmSignature;
|
||||
this.genericSignature = genericSignature;
|
||||
this.kotlinSignature = kotlinSignature;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ActualSignature readSignature(String className, final String methodName) throws Exception {
|
||||
// ugly unreadable code begin
|
||||
FileInputStream classInputStream = new FileInputStream(tmpdir + "/" + className.replace('.', '/') + ".class");
|
||||
try {
|
||||
class Visitor extends EmptyVisitor {
|
||||
ActualSignature readSignature;
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, final String desc, final String signature, String[] exceptions) {
|
||||
if (name.equals(methodName)) {
|
||||
|
||||
final int parameterCount = new Method(name, desc).getArgumentTypes().length;
|
||||
|
||||
return new EmptyVisitor() {
|
||||
String typeParameters = "";
|
||||
String returnType;
|
||||
String[] parameterTypes = new String[parameterCount];
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
if (desc.equals(JvmStdlibNames.JET_METHOD.getDescriptor())) {
|
||||
return new EmptyVisitor() {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
if (name.equals(JvmStdlibNames.JET_METHOD_TYPE_PARAMETERS_FIELD)) {
|
||||
typeParameters = (String) value;
|
||||
}
|
||||
else if (name.equals(JvmStdlibNames.JET_METHOD_RETURN_TYPE_FIELD)) {
|
||||
returnType = (String) value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitParameterAnnotation(final int parameter, String desc, boolean visible) {
|
||||
if (desc.equals(JvmStdlibNames.JET_VALUE_PARAMETER.getDescriptor())) {
|
||||
return new EmptyVisitor() {
|
||||
@Override
|
||||
public void visit(String name, Object value) {
|
||||
if (name.equals(JvmStdlibNames.JET_VALUE_PARAMETER_TYPE_FIELD)) {
|
||||
parameterTypes[parameter] = (String) value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotationDefault() {
|
||||
return new EmptyVisitor();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String makeKotlinSignature() {
|
||||
boolean allNulls = true;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(typeParameters);
|
||||
if (typeParameters != null && typeParameters.length() > 0) {
|
||||
allNulls = false;
|
||||
}
|
||||
sb.append("(");
|
||||
for (String parameterType : parameterTypes) {
|
||||
sb.append(parameterType);
|
||||
if (parameterType != null) {
|
||||
allNulls = false;
|
||||
}
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(returnType);
|
||||
if (returnType != null) {
|
||||
allNulls = false;
|
||||
}
|
||||
if (allNulls) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
Assert.assertNull(readSignature);
|
||||
readSignature = new ActualSignature(desc, signature, makeKotlinSignature());
|
||||
}
|
||||
};
|
||||
}
|
||||
return super.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
Visitor visitor = new Visitor();
|
||||
|
||||
new ClassReader(classInputStream).accept(visitor,
|
||||
ClassReader.SKIP_CODE|ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);
|
||||
|
||||
Assert.assertNotNull("method not found: " + className + "::" + methodName, visitor.readSignature);
|
||||
|
||||
return visitor.readSignature;
|
||||
} finally {
|
||||
Closeables.closeQuietly(classInputStream);
|
||||
}
|
||||
// ugly unreadable code end
|
||||
}
|
||||
|
||||
private static class Expectation {
|
||||
private final String className;
|
||||
private final String methodName;
|
||||
private final String jvmSignature;
|
||||
private final String genericSignature;
|
||||
private final String kotlinSignature;
|
||||
|
||||
private Expectation(@NotNull String className, @NotNull String methodName,
|
||||
@NotNull String jvmSignature, @Nullable String genericSignature, @Nullable String kotlinSignature) {
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
this.jvmSignature = jvmSignature;
|
||||
this.genericSignature = genericSignature;
|
||||
this.kotlinSignature = kotlinSignature;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static final Pattern methodPattern = Pattern.compile("^// method: *(.*)::(.*?) *(//.*)?");
|
||||
private static final Pattern jvmSignaturePattern = Pattern.compile("^// jvm signature: *(.+?) *(//.*)?");
|
||||
private static final Pattern genericSignaturePattern = Pattern.compile("^// generic signature: *(.+?) *(//.*)?");
|
||||
private static final Pattern kotlinSignaturePattern = Pattern.compile("^// kotlin signature: *(.+?) *(//.*)?");
|
||||
private Expectation parseExpectations() throws IOException {
|
||||
List<String> lines = Files.readLines(ktFile, Charset.forName("utf-8"));
|
||||
for (int i = 0; i < lines.size() - 3; ++i) {
|
||||
Matcher methodMatcher = methodPattern.matcher(lines.get(i));
|
||||
if (methodMatcher.matches()) {
|
||||
Matcher jvmSignatureMatcher = jvmSignaturePattern.matcher(lines.get(i + 1));
|
||||
Matcher genericSignatureMatcher = genericSignaturePattern.matcher(lines.get(i + 2));
|
||||
Matcher kotlinSignatureMatcher = kotlinSignaturePattern.matcher(lines.get(i + 3));
|
||||
if (!jvmSignatureMatcher.matches() || !genericSignatureMatcher.matches() || !kotlinSignatureMatcher.matches()) {
|
||||
throw new AssertionError("'method:' must be followed ... bla bla ... use the source luke");
|
||||
}
|
||||
|
||||
String className = methodMatcher.group(1);
|
||||
String methodName = methodMatcher.group(2);
|
||||
|
||||
String jvmSignature = jvmSignatureMatcher.group(1);
|
||||
String genericSignature = genericSignatureMatcher.group(1);
|
||||
String kotlinSignature = kotlinSignatureMatcher.group(1);
|
||||
if (genericSignature.equals("null")) {
|
||||
genericSignature = null;
|
||||
}
|
||||
if (kotlinSignature.equals("null")) {
|
||||
kotlinSignature = null;
|
||||
}
|
||||
return new Expectation(className, methodName, jvmSignature, genericSignature, kotlinSignature);
|
||||
}
|
||||
}
|
||||
throw new AssertionError("test instructions not found in " + ktFile);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBuilder.suiteForDirectory(JetTestCaseBuilder.getTestDataPathBase(), "/writeSignature", true, new JetTestCaseBuilder.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||
return new WriteSignatureTest(file);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.longTest;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class LibFromMaven {
|
||||
@NotNull
|
||||
private final String org;
|
||||
@NotNull
|
||||
private final String module;
|
||||
@NotNull
|
||||
private final String rev;
|
||||
|
||||
public LibFromMaven(@NotNull String org, @NotNull String module, @NotNull String rev) {
|
||||
this.org = org;
|
||||
this.module = module;
|
||||
this.rev = rev;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getOrg() {
|
||||
return org;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getRev() {
|
||||
return rev;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return org + "/" + module + "/" + rev;
|
||||
}
|
||||
}
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jet.compiler.longTest;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
|
||||
import org.apache.commons.httpclient.methods.GetMethod;
|
||||
import org.apache.commons.httpclient.params.HttpMethodParams;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.CompileCompilerDependenciesTest;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.TimeUtils;
|
||||
import org.jetbrains.jet.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
|
||||
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
|
||||
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* @author Stepan Koltsov
|
||||
*/
|
||||
public class ResolveDescriptorsFromExternalLibraries {
|
||||
|
||||
@NotNull
|
||||
private final CompilerDependencies compilerDependencies;
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ResolveDescriptorsFromExternalLibraries().run();
|
||||
System.out.println("$");
|
||||
}
|
||||
|
||||
|
||||
public ResolveDescriptorsFromExternalLibraries() {
|
||||
System.out.println("Getting compiler dependencies");
|
||||
compilerDependencies = CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true);
|
||||
}
|
||||
|
||||
private void run() throws Exception {
|
||||
testLibrary("com.google.guava", "guava", "12.0-rc2");
|
||||
testLibrary("org.springframework", "spring-core", "3.1.1.RELEASE");
|
||||
}
|
||||
|
||||
private void testLibrary(@NotNull String org, @NotNull String module, @NotNull String rev) throws Exception {
|
||||
LibFromMaven lib = new LibFromMaven(org, module, rev);
|
||||
File jar = getLibrary(lib);
|
||||
System.out.println("Testing library " + lib + "...");
|
||||
System.out.println("Using file " + jar);
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
Disposable junk = new Disposable() {
|
||||
@Override
|
||||
public void dispose() { }
|
||||
};
|
||||
|
||||
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdk(junk);
|
||||
jetCoreEnvironment.addToClasspath(jar);
|
||||
|
||||
|
||||
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(compilerDependencies, jetCoreEnvironment.getProject());
|
||||
|
||||
FileInputStream is = new FileInputStream(jar);
|
||||
try {
|
||||
ZipInputStream zip = new ZipInputStream(is);
|
||||
for (;;) {
|
||||
ZipEntry entry = zip.getNextEntry();
|
||||
if (entry == null) {
|
||||
break;
|
||||
}
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.endsWith(".class")) {
|
||||
continue;
|
||||
}
|
||||
if (entryName.matches("(.*/|)package-info\\.class")) {
|
||||
continue;
|
||||
}
|
||||
if (entryName.contains("$")) {
|
||||
continue;
|
||||
}
|
||||
String className = entryName.substring(0, entryName.length() - ".class".length()).replace("/", ".");
|
||||
ClassDescriptor clazz = injector.getJavaDescriptorResolver().resolveClass(new FqName(className), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
|
||||
if (clazz == null) {
|
||||
throw new IllegalStateException("class not found by name " + className + " in " + lib);
|
||||
}
|
||||
clazz.getDefaultType().getMemberScope().getAllDescriptors();
|
||||
}
|
||||
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
|
||||
Disposer.dispose(junk);
|
||||
}
|
||||
|
||||
System.out.println("Testing library " + lib + " done in " + TimeUtils.millisecondsToSecondsString(System.currentTimeMillis() - start) + "s");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getLibrary(@NotNull LibFromMaven lib) throws Exception {
|
||||
File userHome = new File(System.getProperty("user.home"));
|
||||
String fileName = lib.getModule() + "-" + lib.getRev() + ".jar";
|
||||
|
||||
File dir = new File(userHome, ".kotlin-project/resolve-libraries/" + lib.getOrg() + "/" + lib.getModule());
|
||||
|
||||
File file = new File(dir, fileName);
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
|
||||
JetTestUtils.mkdirs(dir);
|
||||
|
||||
File tmp = new File(dir, fileName + "~");
|
||||
|
||||
String uri = url(lib);
|
||||
GetMethod method = new GetMethod(uri);
|
||||
|
||||
FileOutputStream os = null;
|
||||
|
||||
System.out.println("Downloading library " + lib + " to " + file);
|
||||
|
||||
MultiThreadedHttpConnectionManager connectionManager = null;
|
||||
try {
|
||||
connectionManager = new MultiThreadedHttpConnectionManager();
|
||||
HttpClient httpClient = new HttpClient(connectionManager);
|
||||
os = new FileOutputStream(tmp);
|
||||
String userAgent = ResolveDescriptorsFromExternalLibraries.class.getName() + "/commons-httpclient";
|
||||
method.getParams().setParameter(HttpMethodParams.USER_AGENT, userAgent);
|
||||
int code = httpClient.executeMethod(method);
|
||||
if (code != 200) {
|
||||
throw new RuntimeException("failed to execute GET " + uri + ", code is " + code);
|
||||
}
|
||||
InputStream responseBodyAsStream = method.getResponseBodyAsStream();
|
||||
if (responseBodyAsStream == null) {
|
||||
throw new RuntimeException("method is executed fine, but response is null");
|
||||
}
|
||||
ByteStreams.copy(responseBodyAsStream, os);
|
||||
os.close();
|
||||
if (!tmp.renameTo(file)) {
|
||||
throw new RuntimeException("failed to rename file: " + tmp + " to " + file);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
finally {
|
||||
if (method != null) {
|
||||
try {
|
||||
method.releaseConnection();
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
}
|
||||
if (connectionManager != null) {
|
||||
try {
|
||||
connectionManager.shutdown();
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
}
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
}
|
||||
catch (Throwable e) {}
|
||||
}
|
||||
tmp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static String url(LibFromMaven lib) {
|
||||
return "http://repo1.maven.org/maven2/" + lib.getOrg().replace(".", "/") + "/" + lib.getModule() + "/" + lib.getRev()
|
||||
+ "/" + lib.getModule() + "-" + lib.getRev() + ".jar";
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.compiler.TranslatingCompiler;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.JdkUtil;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -43,6 +44,7 @@ import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
import org.jetbrains.jet.plugin.project.JsModuleDetector;
|
||||
import org.jetbrains.jet.utils.PathUtil;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
@@ -71,7 +73,14 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
|
||||
@Override
|
||||
public boolean isCompilableFile(VirtualFile virtualFile, CompileContext compileContext) {
|
||||
return virtualFile.getFileType() instanceof JetFileType;
|
||||
if (!(virtualFile.getFileType() instanceof JetFileType)) {
|
||||
return false;
|
||||
}
|
||||
Project project = compileContext.getProject();
|
||||
if (project == null || JsModuleDetector.isJsProject(project)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -316,7 +325,7 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
private static int execInProcess(File kotlinHome, VirtualFile outputDir, File scriptFile, PrintStream out, CompileContext context) {
|
||||
URLClassLoader loader = getOrCreateClassLoader(kotlinHome, context);
|
||||
try {
|
||||
String compilerClassName = "org.jetbrains.jet.cli.KotlinCompiler";
|
||||
String compilerClassName = "org.jetbrains.jet.cli.jvm.K2JVMCompiler";
|
||||
Class<?> kompiler = Class.forName(compilerClassName, true, loader);
|
||||
Method exec = kompiler.getDeclaredMethod("exec", PrintStream.class, String[].class);
|
||||
|
||||
@@ -326,9 +335,9 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
context.addMessage(INFORMATION, "Invoking in-process compiler " + compilerClassName + " with arguments " + Arrays.asList(arguments), "", -1, -1);
|
||||
|
||||
Object rc = exec.invoke(kompiler.newInstance(), out, arguments);
|
||||
// exec() returns a KotlinCompiler.ExitCode object, that class is not accessible here,
|
||||
// exec() returns a K2JVMCompiler.ExitCode object, that class is not accessible here,
|
||||
// so we take it's contents through reflection
|
||||
if ("org.jetbrains.jet.cli.KotlinCompiler.ExitCode".equals(rc.getClass().getCanonicalName())) {
|
||||
if ("org.jetbrains.jet.cli.jvm.K2JVMCompiler.ExitCode".equals(rc.getClass().getCanonicalName())) {
|
||||
return (Integer) rc.getClass().getMethod("getCode").invoke(rc);
|
||||
}
|
||||
else {
|
||||
@@ -372,7 +381,7 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
private static void runOutOfProcess(final CompileContext compileContext, final OutputItemsCollector collector, VirtualFile outputDir, File kotlinHome, File scriptFile) {
|
||||
final SimpleJavaParameters params = new SimpleJavaParameters();
|
||||
params.setJdk(new SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome()));
|
||||
params.setMainClass("org.jetbrains.jet.cli.KotlinCompiler");
|
||||
params.setMainClass("org.jetbrains.jet.cli.jvm.K2JVMCompiler");
|
||||
|
||||
for (String arg : commandLineArguments(outputDir, scriptFile)) {
|
||||
params.getProgramParametersList().add(arg);
|
||||
|
||||
@@ -31,8 +31,11 @@ import java.util.Collections;
|
||||
public class JetCompilerManager implements ProjectComponent {
|
||||
public JetCompilerManager(CompilerManager manager) {
|
||||
manager.addTranslatingCompiler(new JetCompiler(),
|
||||
Collections.<FileType>singleton(JetFileType.INSTANCE),
|
||||
Collections.singleton(StdFileTypes.CLASS));
|
||||
Collections.<FileType>singleton(JetFileType.INSTANCE),
|
||||
Collections.singleton(StdFileTypes.CLASS));
|
||||
manager.addTranslatingCompiler(new K2JSCompiler(),
|
||||
Collections.<FileType>singleton(JetFileType.INSTANCE),
|
||||
Collections.<FileType>singleton(StdFileTypes.JS));
|
||||
manager.addCompilableFileType(JetFileType.INSTANCE);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.di.InjectorForMacros;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.TipsManager;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
|
||||
@@ -28,7 +28,8 @@ import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.testFramework.PlatformTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
@@ -61,9 +62,9 @@ public abstract class AbstractLibrariesTest extends PlatformTestCase {
|
||||
});
|
||||
librarySourceDir = LocalFileSystem.getInstance().findFileByPath(TEST_DATA_PATH + "/library");
|
||||
assertNotNull(librarySourceDir);
|
||||
KotlinCompiler.ExitCode compilerExec =
|
||||
new KotlinCompiler().exec(System.out, "-src", librarySourceDir.getPath(), "-output", libraryIoDir.getAbsolutePath());
|
||||
assertEquals(KotlinCompiler.ExitCode.OK, compilerExec);
|
||||
ExitCode compilerExec =
|
||||
new K2JVMCompiler().exec(System.out, "-src", librarySourceDir.getPath(), "-output", libraryIoDir.getAbsolutePath());
|
||||
assertEquals(ExitCode.OK, compilerExec);
|
||||
libraryDir = LocalFileSystem.getInstance().findFileByIoFile(libraryIoDir);
|
||||
assertNotNull(libraryDir);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.testFramework.UsefulTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.compiler.JetCoreEnvironment;
|
||||
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
|
||||
+5
-5
@@ -17,8 +17,8 @@
|
||||
package org.jetbrains.kotlin.maven.doc;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.jetbrains.jet.cli.CompilerArguments;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
import org.jetbrains.kotlin.doc.KDocArguments;
|
||||
import org.jetbrains.kotlin.doc.KDocCompiler;
|
||||
import org.jetbrains.kotlin.doc.KDocConfig;
|
||||
@@ -164,17 +164,17 @@ public class KDocMojo extends KotlinCompileMojoBase {
|
||||
private Map<String, String> packageSummaryText;
|
||||
|
||||
@Override
|
||||
protected KotlinCompiler createCompiler() {
|
||||
protected K2JVMCompiler createCompiler() {
|
||||
return new KDocCompiler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompilerArguments createCompilerArguments() {
|
||||
protected K2JVMCompilerArguments createCompilerArguments() {
|
||||
return new KDocArguments();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
|
||||
protected void configureCompilerArguments(K2JVMCompilerArguments arguments) throws MojoExecutionException {
|
||||
configureBaseCompilerArguments(getLog(), arguments, docModule, sources, classpath, output);
|
||||
|
||||
if (arguments instanceof KDocArguments) {
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import java.util.*
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext.*
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.Collection
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext.*
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
|
||||
@@ -2,25 +2,25 @@ package org.jetbrains.kotlin.doc
|
||||
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import org.jetbrains.jet.cli.CompilerArguments
|
||||
import org.jetbrains.jet.cli.KotlinCompiler
|
||||
import org.jetbrains.jet.compiler.CompileEnvironmentConfiguration
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentConfiguration
|
||||
import org.jetbrains.kotlin.doc.highlighter.HtmlCompilerPlugin
|
||||
|
||||
/**
|
||||
* Main for running the KDocCompiler
|
||||
*/
|
||||
fun main(args: Array<String?>): Unit {
|
||||
KotlinCompiler.doMain(KDocCompiler(), args);
|
||||
K2JVMCompiler.doMain(KDocCompiler(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of the [[KotlinCompiler]] which includes the [[KDoc]] compiler plugin and allows
|
||||
* A version of the [[K2JVMCompiler]] which includes the [[KDoc]] compiler plugin and allows
|
||||
* command line validation or for the configuration to be provided via [[KDocArguments]]
|
||||
*/
|
||||
class KDocCompiler() : KotlinCompiler() {
|
||||
class KDocCompiler() : K2JVMCompiler() {
|
||||
|
||||
protected override fun configureEnvironment(configuration : CompileEnvironmentConfiguration?, arguments : CompilerArguments?) {
|
||||
protected override fun configureEnvironment(configuration : CompileEnvironmentConfiguration?, arguments : K2JVMCompilerArguments?) {
|
||||
super.configureEnvironment(configuration, arguments)
|
||||
val coreEnvironment = configuration?.getEnvironment()
|
||||
if (coreEnvironment != null) {
|
||||
@@ -38,7 +38,7 @@ class KDocCompiler() : KotlinCompiler() {
|
||||
}
|
||||
}
|
||||
|
||||
protected override fun createArguments() : CompilerArguments? {
|
||||
protected override fun createArguments() : K2JVMCompilerArguments? {
|
||||
return KDocArguments()
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class KDocCompiler() : KotlinCompiler() {
|
||||
}
|
||||
}
|
||||
|
||||
class KDocArguments() : CompilerArguments() {
|
||||
class KDocArguments() : K2JVMCompilerArguments() {
|
||||
|
||||
public var docConfig: KDocConfig = KDocConfig()
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package org.jetbrains.kotlin.doc.highlighter
|
||||
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin
|
||||
import org.jetbrains.jet.compiler.CompilerPluginContext
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin
|
||||
import org.jetbrains.jet.cli.common.CompilerPluginContext
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package org.jetbrains.kotlin.doc.model
|
||||
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin
|
||||
import org.jetbrains.jet.compiler.CompilerPluginContext
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin
|
||||
import org.jetbrains.jet.cli.common.CompilerPluginContext
|
||||
import org.jetbrains.kotlin.doc.KDocConfig
|
||||
|
||||
/** Base class for any compiler plugin which needs to process a KModel */
|
||||
|
||||
@@ -2,8 +2,8 @@ package test.kotlin.kdoc
|
||||
|
||||
import java.io.File
|
||||
import kotlin.test.assertTrue
|
||||
import org.jetbrains.jet.cli.CompilerArguments
|
||||
import org.jetbrains.jet.cli.KotlinCompiler
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.doc.highlighter.HtmlCompilerPlugin
|
||||
import org.junit.Test
|
||||
|
||||
@@ -20,12 +20,12 @@ class HtmlVisitorTest {
|
||||
val outDir = File(dir, "target/htmldocs")
|
||||
println("Generating source HTML to $outDir")
|
||||
|
||||
val args = CompilerArguments()
|
||||
val args = K2JVMCompilerArguments()
|
||||
args.setSrc(srcDir.toString())
|
||||
args.setOutputDir(File(dir, "target/classes-htmldocs").toString())
|
||||
args.getCompilerPlugins()?.add(HtmlCompilerPlugin())
|
||||
|
||||
val compiler = KotlinCompiler()
|
||||
val compiler = K2JVMCompiler()
|
||||
compiler.exec(System.out, args)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.maven;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.jetbrains.jet.cli.CompilerArguments;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments;
|
||||
|
||||
/**
|
||||
* Converts Kotlin to JavaScript code
|
||||
@@ -36,7 +36,7 @@ public class K2JSCompilerMojo extends KotlinCompileMojo {
|
||||
private String outFile;
|
||||
|
||||
@Override
|
||||
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
|
||||
protected void configureCompilerArguments(K2JVMCompilerArguments arguments) throws MojoExecutionException {
|
||||
super.configureCompilerArguments(arguments);
|
||||
|
||||
K2JSCompilerPlugin plugin = new K2JSCompilerPlugin();
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.maven;
|
||||
import com.google.common.io.Files;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.compiler.CompilerPlugin;
|
||||
import org.jetbrains.jet.compiler.CompilerPluginContext;
|
||||
import org.jetbrains.jet.cli.common.CompilerPlugin;
|
||||
import org.jetbrains.jet.cli.common.CompilerPluginContext;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.k2js.config.Config;
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@
|
||||
package org.jetbrains.kotlin.maven;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.jetbrains.jet.cli.CompilerArguments;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments;
|
||||
|
||||
/**
|
||||
* Compiles kotlin sources
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.jet.cli.CompilerArguments;
|
||||
*/
|
||||
public class KotlinCompileMojo extends KotlinCompileMojoBase {
|
||||
@Override
|
||||
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
|
||||
protected void configureCompilerArguments(K2JVMCompilerArguments arguments) throws MojoExecutionException {
|
||||
configureBaseCompilerArguments(getLog(), arguments, module, sources, classpath, output);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-12
@@ -23,8 +23,10 @@ import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugin.logging.Log;
|
||||
import org.jetbrains.jet.cli.CompilerArguments;
|
||||
import org.jetbrains.jet.cli.KotlinCompiler;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompiler;
|
||||
import org.jetbrains.jet.cli.common.ExitCode.*;
|
||||
import org.jetbrains.jet.cli.common.ExitCode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -104,15 +106,15 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo {
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
final CompilerArguments arguments = createCompilerArguments();
|
||||
final K2JVMCompilerArguments arguments = createCompilerArguments();
|
||||
|
||||
configureCompilerArguments(arguments);
|
||||
|
||||
final KotlinCompiler compiler = createCompiler();
|
||||
final K2JVMCompiler compiler = createCompiler();
|
||||
|
||||
printCompilerArgumentsIfDebugEnabled(arguments, compiler);
|
||||
|
||||
final KotlinCompiler.ExitCode exitCode = compiler.exec(System.err, arguments);
|
||||
final ExitCode exitCode = compiler.exec(System.err, arguments);
|
||||
|
||||
switch (exitCode) {
|
||||
case COMPILATION_ERROR:
|
||||
@@ -123,7 +125,7 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
|
||||
private void printCompilerArgumentsIfDebugEnabled(CompilerArguments arguments, KotlinCompiler compiler) {
|
||||
private void printCompilerArgumentsIfDebugEnabled(K2JVMCompilerArguments arguments, K2JVMCompiler compiler) {
|
||||
if (getLog().isDebugEnabled()) {
|
||||
getLog().debug("Invoking compiler " + compiler + " with arguments:");
|
||||
try {
|
||||
@@ -142,24 +144,24 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo {
|
||||
}
|
||||
}
|
||||
|
||||
protected KotlinCompiler createCompiler() {
|
||||
return new KotlinCompiler();
|
||||
protected K2JVMCompiler createCompiler() {
|
||||
return new K2JVMCompiler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can create custom compiler argument implementations
|
||||
* such as for KDoc
|
||||
*/
|
||||
protected CompilerArguments createCompilerArguments() {
|
||||
return new CompilerArguments();
|
||||
protected K2JVMCompilerArguments createCompilerArguments() {
|
||||
return new K2JVMCompilerArguments();
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes can register custom plugins or configurations
|
||||
*/
|
||||
protected abstract void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException;
|
||||
protected abstract void configureCompilerArguments(K2JVMCompilerArguments arguments) throws MojoExecutionException;
|
||||
|
||||
protected void configureBaseCompilerArguments(Log log, CompilerArguments arguments, String module,
|
||||
protected void configureBaseCompilerArguments(Log log, K2JVMCompilerArguments arguments, String module,
|
||||
List<String> sources, List<String> classpath, String output) throws MojoExecutionException {
|
||||
// don't include runtime, it should be in maven dependencies
|
||||
arguments.mode = "stdlib";
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.maven;
|
||||
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.jetbrains.jet.cli.CompilerArguments;
|
||||
import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments;
|
||||
|
||||
/**
|
||||
* Compiles Kotlin test sources
|
||||
@@ -47,7 +47,7 @@ public class KotlinTestCompileMojo extends KotlinCompileMojoBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureCompilerArguments(CompilerArguments arguments) throws MojoExecutionException {
|
||||
protected void configureCompilerArguments(K2JVMCompilerArguments arguments) throws MojoExecutionException {
|
||||
configureBaseCompilerArguments(
|
||||
getLog(), arguments,
|
||||
testModule, testSources, testClasspath, testOutput);
|
||||
|
||||
Reference in New Issue
Block a user