refactoring of script definition api

This commit is contained in:
Alex Tkachman
2012-07-30 09:26:30 +03:00
parent 003b2c64a7
commit c14a0b3c84
13 changed files with 201 additions and 37 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import com.google.common.collect.Lists;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
@@ -25,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JdkNames;
@@ -252,13 +254,19 @@ public class ScriptCodegen {
}
public static String classNameForScript(JetFile file) {
JetScriptDefinition scriptDefinition = JetParserDefinition.getInstance().findScriptDefinition(file);
JetScriptDefinition scriptDefinition = JetScriptDefinitionProvider.getInstance(file.getProject()).findScriptDefinition(file);
String name = file.getName();
name = name.substring(0, name.length()-scriptDefinition.getExtension().length());
int index = name.lastIndexOf('/');
if(index != -1)
name = name.substring(index+1);
if(name.endsWith(scriptDefinition.getExtension()))
name = name.substring(0, name.length()-scriptDefinition.getExtension().length());
else {
index = name.indexOf('.');
if(index != -1)
name = name.substring(0,index);
}
name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
JetNamespaceHeader header = file.getNamespaceHeader();
if(header != null && header.getName().length() > 0) {
@@ -38,6 +38,7 @@ import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.lang.parsing.JetParser;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.resolve.java.extAnnotations.CoreAnnotationsProvider;
@@ -89,6 +90,7 @@ public class JetCoreEnvironment {
projectEnvironment = new JavaCoreProjectEnvironment(parentDisposable, applicationEnvironment);
MockProject project = projectEnvironment.getProject();
project.registerService(JetScriptDefinitionProvider.class, new JetScriptDefinitionProvider());
project.registerService(JetFilesProvider.class, new CliJetFilesProvider(this));
project.registerService(CoreJavaFileManager.class, (CoreJavaFileManager) ServiceManager.getService(project, JavaFileManager.class));
Extensions.getArea(project)
@@ -108,6 +110,8 @@ public class JetCoreEnvironment {
addSources(path);
}
JetScriptDefinitionProvider.getInstance(project).addScriptDefinitions(configuration.getList(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY));
JetStandardLibrary.initialize(project);
initialized = true;
}
@@ -37,6 +37,9 @@ import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.lang.BuiltinsScopeExtensionMode;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
@@ -361,24 +364,29 @@ public class KotlinToJVMBytecodeCompiler {
public static Class compileScript(
ClassLoader parentLoader,
String scriptPath,
List<AnalyzerScriptParameter> scriptParameters) {
@Nullable List<AnalyzerScriptParameter> scriptParameters,
@Nullable List<JetScriptDefinition> scriptDefinitions) {
final MessageRenderer messageRenderer = MessageRenderer.PLAIN;
PrintingMessageCollector messageCollector = new PrintingMessageCollector(System.err, messageRenderer, false);
Disposable rootDisposable = CompileEnvironmentUtil.createMockDisposable();
try {
CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
compilerConfiguration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(parentLoader));
compilerConfiguration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, Collections.singletonList(CompilerPathUtil.getJdkAnnotationsPath()));
compilerConfiguration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, Collections.singletonList(
CompilerPathUtil.getJdkAnnotationsPath()));
compilerConfiguration.add(CommonConfigurationKeys.SOURCE_ROOTS_KEY, scriptPath);
compilerConfiguration.addAll(CommonConfigurationKeys.SCRIPT_DEFINITIONS_KEY,
scriptDefinitions != null ? scriptDefinitions : Collections.<JetScriptDefinition>emptyList());
JetCoreEnvironment environment = JetCoreEnvironment.createCoreEnvironmentForJVM(rootDisposable, compilerConfiguration);
K2JVMCompileEnvironmentConfiguration configuration = new K2JVMCompileEnvironmentConfiguration(
environment, messageCollector, scriptParameters,
environment, messageCollector, scriptParameters != null ? scriptParameters : Collections.<AnalyzerScriptParameter>emptyList(),
BuiltinsScopeExtensionMode.ALL,
false,
BuiltinToJavaTypesMapping.ENABLED);
try {
JetScriptDefinitionProvider.getInstance(environment.getProject()).markFileAsScript(environment.getSourceFiles().get(0));
return compileScript(configuration, parentLoader);
}
catch (CompilationException e) {
@@ -17,6 +17,8 @@
package org.jetbrains.jet.config;
import com.intellij.openapi.util.Key;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import java.io.File;
import java.util.List;
@@ -30,4 +32,6 @@ public class CommonConfigurationKeys {
}
public static final Key<List<String>> SOURCE_ROOTS_KEY = Key.create("source roots");
public static final Key<List<JetScriptDefinition>> SCRIPT_DEFINITIONS_KEY = Key.create("script definitions");
}
@@ -22,15 +22,20 @@ package org.jetbrains.jet.lang.parsing;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.file.impl.JavaFileManager;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
public class JetParser implements PsiParser {
private JetParserDefinition parserDefinition;
public JetParser(JetParserDefinition parserDefinition) {
this.parserDefinition = parserDefinition;
public static final String STD_SCRIPT_EXT = "." + JetParserDefinition.KTSCRIPT_FILE_SUFFIX;
private final JetScriptDefinitionProvider scriptDefinitionProvider;
public JetParser(Project project) {
scriptDefinitionProvider = JetScriptDefinitionProvider.getInstance(project);
}
@Override
@@ -43,7 +48,7 @@ public class JetParser implements PsiParser {
@NotNull
public ASTNode parse(IElementType iElementType, PsiBuilder psiBuilder, PsiFile psiFile) {
JetParsing jetParsing = JetParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(psiBuilder));
if (parserDefinition.isScript(psiFile)) {
if (scriptDefinitionProvider != null && scriptDefinitionProvider.isScript(psiFile) || psiFile.getName().endsWith(STD_SCRIPT_EXT)) {
jetParsing.parseScript();
}
else {
@@ -50,13 +50,7 @@ import java.util.Map;
public class JetParserDefinition implements ParserDefinition {
public static final String KTSCRIPT_FILE_SUFFIX = "ktscript";
private HashMap<String,JetScriptDefinition> scripts = new HashMap<String, JetScriptDefinition>();
public JetParserDefinition() {
// .ktscript will take parameters explicitly specified on compilation
JetScriptDefinition standardScript = new JetScriptDefinition(".ktscript", Collections.<AnalyzerScriptParameter>emptyList());
addScriptDefinition(standardScript);
//todo: ApplicationManager.getApplication() is null during JetParsingTest setting up
/*if (!ApplicationManager.getApplication().isCommandLine()) {
@@ -76,7 +70,7 @@ public class JetParserDefinition implements ParserDefinition {
@Override
public PsiParser createParser(Project project) {
return new JetParser(this);
return new JetParser(project);
}
@Override
@@ -121,21 +115,4 @@ public class JetParserDefinition implements ParserDefinition {
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode astNode, ASTNode astNode1) {
return SpaceRequirements.MAY;
}
public JetScriptDefinition findScriptDefinition(PsiFile psiFile) {
String name = psiFile.getName();
for (Map.Entry<String, JetScriptDefinition> e : scripts.entrySet()) {
if(name.endsWith(e.getKey()))
return e.getValue();
}
return null;
}
public boolean isScript(PsiFile psiFile) {
return findScriptDefinition(psiFile) != null;
}
public void addScriptDefinition(@NotNull JetScriptDefinition scriptDefinition) {
scripts.put(scriptDefinition.getExtension(), scriptDefinition);
}
}
@@ -0,0 +1,75 @@
/*
* 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.lang.parsing;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import java.util.*;
public class JetScriptDefinitionProvider {
private final HashMap<String,JetScriptDefinition> scripts = new HashMap<String, JetScriptDefinition>();
private final HashSet<PsiFile> scriptsFiles = new HashSet<PsiFile>();
private static JetScriptDefinition standardScript = new JetScriptDefinition(".ktscript", Collections.<AnalyzerScriptParameter>emptyList());
public JetScriptDefinitionProvider() {
// .ktscript will take analyzer parameters explicitly specified on compilation
addScriptDefinition(standardScript);
}
public void markFileAsScript(JetFile file) {
scriptsFiles.add(file);
}
public static JetScriptDefinitionProvider getInstance(Project project) {
return ServiceManager.getService(project, JetScriptDefinitionProvider.class);
}
public JetScriptDefinition findScriptDefinition(PsiFile psiFile) {
boolean force = scriptsFiles.contains(psiFile);
String name = psiFile.getName();
for (Map.Entry<String, JetScriptDefinition> e : scripts.entrySet()) {
if (name.endsWith(e.getKey())) {
return e.getValue();
}
}
if(force)
return standardScript;
return null;
}
public boolean isScript(PsiFile psiFile) {
return findScriptDefinition(psiFile) != null;
}
public void addScriptDefinition(@NotNull JetScriptDefinition scriptDefinition) {
scripts.put(scriptDefinition.getExtension(), scriptDefinition);
}
public void addScriptDefinitions(List<JetScriptDefinition> definitions) {
for (JetScriptDefinition definition : definitions) {
addScriptDefinition(definition);
}
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.util.Key;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
@@ -24,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetScript;
@@ -154,7 +156,7 @@ public class ScriptHeaderResolver {
scope.setImplicitReceiver(descriptor.getImplicitReceiver());
JetFile file = (JetFile) declaration.getContainingFile();
JetScriptDefinition scriptDefinition = JetParserDefinition.getInstance().findScriptDefinition(file);
JetScriptDefinition scriptDefinition = JetScriptDefinitionProvider.getInstance(file.getProject()).findScriptDefinition(file);
int index = 0;
List<AnalyzerScriptParameter> scriptParameters = !scriptDefinition.getScriptParameters().isEmpty()
+10
View File
@@ -0,0 +1,10 @@
// this script expected parameter num : Int
fun fib(n: Int): Int {
val v = if(n < 2) 1 else fib(n-1) + fib(n-2)
System.out.println("fib($n)=$v")
return v
}
System.out.println("num: $num")
val result = fib(num)
+10
View File
@@ -0,0 +1,10 @@
// this script expected parameter num : Int
fun fib(n: Int): Int {
val v = if(n < 2) 1 else fib(n-1) + fib(n-2)
System.out.println("fib($n)=$v")
return v
}
System.out.println("num: $num")
val result = fib(num)
@@ -22,6 +22,7 @@ import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.cli.common.ExitCode;
import org.jetbrains.jet.cli.jvm.compiler.KotlinToJVMBytecodeCompiler;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.ref.JetTypeName;
@@ -37,6 +38,7 @@ import java.io.File;
import java.io.PrintStream;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@@ -132,7 +134,58 @@ public class CliTest {
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.ktscript", scriptParameters);
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.ktscript", scriptParameters, null);
Assert.assertNotNull(aClass);
try {
aClass.getConstructor(int.class).newInstance(4);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testScriptStandardExt() {
LinkedList<AnalyzerScriptParameter> scriptParameters = new LinkedList<AnalyzerScriptParameter>();
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.kt", scriptParameters, null);
Assert.assertNotNull(aClass);
try {
aClass.getConstructor(int.class).newInstance(4);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testScriptWithoutScriptDefinition() {
LinkedList<AnalyzerScriptParameter> scriptParameters = new LinkedList<AnalyzerScriptParameter>();
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.fib.kt", scriptParameters, null);
Assert.assertNotNull(aClass);
try {
aClass.getConstructor(int.class).newInstance(4);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@Test
public void testScriptWithScriptDefinition() {
LinkedList<AnalyzerScriptParameter> scriptParameters = new LinkedList<AnalyzerScriptParameter>();
AnalyzerScriptParameter parameter = new AnalyzerScriptParameter(Name.identifier("num"), JetTypeName.parse("jet.Int"));
scriptParameters.add(parameter);
Class aClass = KotlinToJVMBytecodeCompiler
.compileScript(getClass().getClassLoader(), "compiler/testData/cli/fib.fib.kt", null, Arrays.asList(new JetScriptDefinition(".fib.kt",scriptParameters)));
Assert.assertNotNull(aClass);
try {
@@ -16,9 +16,11 @@
package org.jetbrains.jet.codegen;
import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.jet.ConfigurationKind;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import java.lang.reflect.Constructor;
@@ -32,6 +34,9 @@ import java.util.List;
*/
public class ScriptGenTest extends CodegenTestCase {
public static final JetScriptDefinition FIB_SCRIPT_DEFINITION =
new JetScriptDefinition(".lang.kt", new AnalyzerScriptParameter("num", "jet.Int"));
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -94,7 +99,7 @@ public class ScriptGenTest extends CodegenTestCase {
}
public void testLanguage() {
JetParserDefinition.getInstance().addScriptDefinition(new JetScriptDefinition(".lang.kt", new AnalyzerScriptParameter("num","jet.Int")));
JetScriptDefinitionProvider.getInstance(myEnvironment.getProject()).addScriptDefinition(FIB_SCRIPT_DEFINITION);
loadFile("script/fib.lang.kt");
final Class aClass = loadClass("Fib", generateClassesInFile());
try {
@@ -109,7 +114,7 @@ public class ScriptGenTest extends CodegenTestCase {
}
public void testLanguageWithPackage() {
JetParserDefinition.getInstance().addScriptDefinition(new JetScriptDefinition(".lang.kt", new AnalyzerScriptParameter("num","jet.Int")));
JetScriptDefinitionProvider.getInstance(myEnvironment.getProject()).addScriptDefinition(FIB_SCRIPT_DEFINITION);
loadFile("script/fibWithPackage.lang.kt");
final Class aClass = loadClass("test.FibWithPackage", generateClassesInFile());
try {
+3
View File
@@ -77,6 +77,9 @@
<projectService serviceInterface="org.jetbrains.jet.lang.resolve.java.JetFilesProvider"
serviceImplementation="org.jetbrains.jet.plugin.project.PluginJetFilesProvider"/>
<projectService serviceInterface="org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider"
serviceImplementation="org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider"/>
<projectService serviceInterface="org.jetbrains.jet.lang.resolve.java.extAnnotations.ExternalAnnotationsProvider"
serviceImplementation="org.jetbrains.jet.plugin.extAnnotations.IdeaExternalAnnotationsProvider"/>