Marked scripting points with // SCRIPT: markers.

This commit is contained in:
Ilya Ryzhenkov
2014-03-17 23:16:54 +04:00
committed by Andrey Breslav
parent 618aea6218
commit e49f4a0722
26 changed files with 39 additions and 1 deletions
@@ -2163,6 +2163,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
} }
else if (descriptor instanceof ScriptReceiver) { else if (descriptor instanceof ScriptReceiver) {
// SCRIPT: generate script
generateScript((ScriptReceiver) descriptor); generateScript((ScriptReceiver) descriptor);
} }
else if (descriptor instanceof ExtensionReceiver) { else if (descriptor instanceof ExtensionReceiver) {
@@ -2196,6 +2197,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return context.lookupInContext(provided, StackValue.local(0, OBJECT_TYPE), state, false); return context.lookupInContext(provided, StackValue.local(0, OBJECT_TYPE), state, false);
} }
// SCRIPT: generate script, move to ScriptingUtil
private void generateScript(@NotNull ScriptReceiver receiver) { private void generateScript(@NotNull ScriptReceiver receiver) {
CodegenContext cur = context; CodegenContext cur = context;
StackValue result = StackValue.local(0, OBJECT_TYPE); StackValue result = StackValue.local(0, OBJECT_TYPE);
@@ -3222,6 +3224,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type varType = asmType(variableDescriptor.getType()); Type varType = asmType(variableDescriptor.getType());
// SCRIPT: Variable at the top of the script is generated as field
if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) { if (JetPsiUtil.isScriptDeclaration(variableDeclaration)) {
generateInitializer.fun(variableDescriptor); generateInitializer.fun(variableDescriptor);
JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration); JetScript scriptPsi = JetPsiUtil.getScript(variableDeclaration);
@@ -37,6 +37,7 @@ public class KotlinCodegenFacade {
) { ) {
for (JetFile file : state.getFiles()) { for (JetFile file : state.getFiles()) {
if (file.isScript()) { if (file.isScript()) {
// SCRIPT: register class name for scripting from this file, move outside of this function
String name = ScriptNameUtil.classNameForScript(file); String name = ScriptNameUtil.classNameForScript(file);
JetScript script = file.getScript(); JetScript script = file.getScript();
assert script != null; assert script != null;
@@ -145,6 +145,7 @@ public class PackageCodegen extends GenerationStateAware {
return; return;
} }
// SCRIPT: Do not write annotations for scripts (if any is??)
for (JetFile file : files) { for (JetFile file : files) {
if (file.isScript()) return; if (file.isScript()) return;
} }
@@ -184,6 +185,7 @@ public class PackageCodegen extends GenerationStateAware {
} }
} }
else if (declaration instanceof JetScript) { else if (declaration instanceof JetScript) {
// SCRIPT: generate script code, should be separate execution branch
ScriptCodegen.createScriptCodegen((JetScript) declaration, state, packagePartContext).generate(); ScriptCodegen.createScriptCodegen((JetScript) declaration, state, packagePartContext).generate();
} }
} }
@@ -40,6 +40,7 @@ import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
// SCRIPT: script code generator
public class ScriptCodegen extends MemberCodegen { public class ScriptCodegen extends MemberCodegen {
public static ScriptCodegen createScriptCodegen( public static ScriptCodegen createScriptCodegen(
@@ -141,6 +141,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
@Override @Override
public void visitJetFile(@NotNull JetFile file) { public void visitJetFile(@NotNull JetFile file) {
if (file.isScript()) { if (file.isScript()) {
// SCRIPT: should be replaced with VisitScript override
//noinspection ConstantConditions //noinspection ConstantConditions
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript())); ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript()));
pushClassDescriptor(classDescriptor); pushClassDescriptor(classDescriptor);
@@ -79,6 +79,7 @@ public class CodegenBinding {
return Boolean.TRUE.equals(bindingContext.get(ENUM_ENTRY_CLASS_NEED_SUBCLASS, classDescriptor)); return Boolean.TRUE.equals(bindingContext.get(ENUM_ENTRY_CLASS_NEED_SUBCLASS, classDescriptor));
} }
// SCRIPT: Generate asmType for script, move to ScriptingUtil
@NotNull @NotNull
public static Type asmTypeForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) { public static Type asmTypeForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) {
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor); ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
@@ -86,6 +87,7 @@ public class CodegenBinding {
return asmType(bindingContext, classDescriptor); return asmType(bindingContext, classDescriptor);
} }
// SCRIPT: Generate asmType for script, move to ScriptingUtil
@NotNull @NotNull
public static Type asmTypeForScriptPsi(BindingContext bindingContext, @NotNull JetScript script) { public static Type asmTypeForScriptPsi(BindingContext bindingContext, @NotNull JetScript script) {
ScriptDescriptor scriptDescriptor = bindingContext.get(SCRIPT, script); ScriptDescriptor scriptDescriptor = bindingContext.get(SCRIPT, script);
@@ -138,6 +140,7 @@ public class CodegenBinding {
return asmType(bindingContext, classDescriptor); return asmType(bindingContext, classDescriptor);
} }
// SCRIPT: register asmType for script descriptor, move to ScriptingUtil
public static void registerClassNameForScript( public static void registerClassNameForScript(
BindingTrace bindingTrace, BindingTrace bindingTrace,
@NotNull ScriptDescriptor scriptDescriptor, @NotNull ScriptDescriptor scriptDescriptor,
@@ -217,6 +220,7 @@ public class CodegenBinding {
innerClasses.add(inner); innerClasses.add(inner);
} }
// SCRIPT: register asmType for script, move to ScriptingUtil
public static void registerClassNameForScript( public static void registerClassNameForScript(
BindingTrace bindingTrace, BindingTrace bindingTrace,
@NotNull JetScript jetScript, @NotNull JetScript jetScript,
@@ -234,6 +238,7 @@ public class CodegenBinding {
// todo: we use Set and add given files but ignoring other scripts because something non-clear kept in binding // todo: we use Set and add given files but ignoring other scripts because something non-clear kept in binding
// for scripts especially in case of REPL // for scripts especially in case of REPL
// SCRIPT: collect fq names for files that are not scripts
HashSet<FqName> names = new HashSet<FqName>(); HashSet<FqName> names = new HashSet<FqName>();
for (JetFile file : files) { for (JetFile file : files) {
if (!file.isScript()) { if (!file.isScript()) {
@@ -197,6 +197,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return new ConstructorContext(descriptor, getContextKind(), this, closure); return new ConstructorContext(descriptor, getContextKind(), this, closure);
} }
// SCRIPT: generate into script, move to ScriptingUtil
@NotNull @NotNull
public ScriptContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) { public ScriptContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) {
return new ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure); return new ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure);
@@ -23,6 +23,7 @@ import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
// SCRIPT: script as field owner context
public class ScriptContext extends FieldOwnerContext<ClassDescriptor> { public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
@NotNull @NotNull
private final ScriptDescriptor scriptDescriptor; private final ScriptDescriptor scriptDescriptor;
@@ -146,6 +146,8 @@ public interface JetNodeTypes {
JetNodeType WHEN_CONDITION_EXPRESSION = new JetNodeType("WHEN_CONDITION_WITH_EXPRESSION", JetWhenConditionWithExpression.class); JetNodeType WHEN_CONDITION_EXPRESSION = new JetNodeType("WHEN_CONDITION_WITH_EXPRESSION", JetWhenConditionWithExpression.class);
JetNodeType PACKAGE_DIRECTIVE = new JetNodeType("PACKAGE_DIRECTIVE", JetPackageDirective.class); JetNodeType PACKAGE_DIRECTIVE = new JetNodeType("PACKAGE_DIRECTIVE", JetPackageDirective.class);
// SCRIPT: script node type
JetNodeType SCRIPT = new JetNodeType("SCRIPT", JetScript.class); JetNodeType SCRIPT = new JetNodeType("SCRIPT", JetScript.class);
IFileElementType TYPE_CODE_FRAGMENT = new JetTypeCodeFragmentType(); IFileElementType TYPE_CODE_FRAGMENT = new JetTypeCodeFragmentType();
@@ -129,6 +129,7 @@ public class JetFile extends PsiFileBase implements JetDeclarationContainer, Jet
@Override @Override
public void setPackageName(String packageName) { } public void setPackageName(String packageName) { }
// SCRIPT: find script in file
@Nullable @Nullable
public JetScript getScript() { public JetScript getScript() {
return PsiTreeUtil.getChildOfType(this, JetScript.class); return PsiTreeUtil.getChildOfType(this, JetScript.class);
@@ -378,10 +378,12 @@ public class JetPsiUtil {
return callOperationNode != null && callOperationNode.getElementType() == JetTokens.SAFE_ACCESS; return callOperationNode != null && callOperationNode.getElementType() == JetTokens.SAFE_ACCESS;
} }
// SCRIPT: is declaration in script?
public static boolean isScriptDeclaration(@NotNull JetDeclaration namedDeclaration) { public static boolean isScriptDeclaration(@NotNull JetDeclaration namedDeclaration) {
return getScript(namedDeclaration) != null; return getScript(namedDeclaration) != null;
} }
// SCRIPT: get script from top-level declaration
@Nullable @Nullable
public static JetScript getScript(@NotNull JetDeclaration namedDeclaration) { public static JetScript getScript(@NotNull JetDeclaration namedDeclaration) {
PsiElement parent = namedDeclaration.getParent(); PsiElement parent = namedDeclaration.getParent();
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
// SCRIPT: Script declaration
public class JetScript extends JetDeclarationImpl { public class JetScript extends JetDeclarationImpl {
public JetScript(@NotNull ASTNode node) { public JetScript(@NotNull ASTNode node) {
@@ -40,6 +40,7 @@ public class PsiJetFileStubImpl extends PsiFileStubImpl<JetFile> implements PsiJ
public PsiJetFileStubImpl(JetFile jetFile, @NotNull StringRef packageName, boolean isScript) { public PsiJetFileStubImpl(JetFile jetFile, @NotNull StringRef packageName, boolean isScript) {
super(jetFile); super(jetFile);
this.packageName = packageName; this.packageName = packageName;
// SCRIPT: PsiJetFileStubImpl knows about scripting
this.isScript = isScript; this.isScript = isScript;
} }
@@ -128,6 +128,7 @@ public class BodyResolver {
resolveFunctionBodies(c); resolveFunctionBodies(c);
// SCRIPT: resolve script bodies
scriptBodyResolverResolver.resolveScriptBodies(c); scriptBodyResolverResolver.resolveScriptBodies(c);
if (!c.getTopDownAnalysisParameters().isDeclaredLocally()) { if (!c.getTopDownAnalysisParameters().isDeclaredLocally()) {
@@ -79,6 +79,7 @@ public class DeclarationResolver {
this.trace = trace; this.trace = trace;
} }
// SCRIPT: inject script header resolver
@Inject @Inject
public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) { public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) {
this.scriptHeaderResolver = scriptHeaderResolver; this.scriptHeaderResolver = scriptHeaderResolver;
@@ -149,6 +150,7 @@ public class DeclarationResolver {
classDescriptor.getBuilder()); classDescriptor.getBuilder());
} }
// SCRIPT: Resolve script declarations, move outside of this function
scriptHeaderResolver.resolveScriptDeclarations(c); scriptHeaderResolver.resolveScriptDeclarations(c);
// TODO : Extensions // TODO : Extensions
@@ -78,6 +78,7 @@ public class ImportsResolver {
WritableScope fileScope = c.getFileScopes().get(file); WritableScope fileScope = c.getFileScopes().get(file);
processImportsInFile(lookupMode, fileScope, Lists.newArrayList(file.getImportDirectives()), file.getPackageFqName().isRoot()); processImportsInFile(lookupMode, fileScope, Lists.newArrayList(file.getImportDirectives()), file.getPackageFqName().isRoot());
} }
// SCRIPT: process script import directives
for (JetScript script : c.getScripts().keySet()) { for (JetScript script : c.getScripts().keySet()) {
WritableScope scriptScope = c.getScriptScopes().get(script); WritableScope scriptScope = c.getScriptScopes().get(script);
processImportsInFile(lookupMode, scriptScope, script.getImportDirectives(), true); processImportsInFile(lookupMode, scriptScope, script.getImportDirectives(), true);
@@ -40,6 +40,8 @@ import java.util.Map;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
// SCRIPT: resolve symbols in scripts
public class ScriptBodyResolver { public class ScriptBodyResolver {
@NotNull @NotNull
@@ -46,6 +46,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
// SCRIPT: Resolve declarations in scripts
public class ScriptHeaderResolver { public class ScriptHeaderResolver {
public static final Key<Integer> PRIORITY_KEY = Key.create(JetScript.class.getName() + ".priority"); public static final Key<Integer> PRIORITY_KEY = Key.create(JetScript.class.getName() + ".priority");
@@ -327,6 +327,8 @@ public class TopDownAnalyzer {
for (ClassDescriptorWithResolutionScopes mutableClassDescriptor : c.getClasses().values()) { for (ClassDescriptorWithResolutionScopes mutableClassDescriptor : c.getClasses().values()) {
((MutableClassDescriptor) mutableClassDescriptor).lockScopes(); ((MutableClassDescriptor) mutableClassDescriptor).lockScopes();
} }
// SCRIPT: extra code for scripts
Set<FqName> scriptFqNames = Sets.newHashSet(); Set<FqName> scriptFqNames = Sets.newHashSet();
for (JetFile file : c.getFileScopes().keySet()) { for (JetFile file : c.getFileScopes().keySet()) {
if (file.isScript()) { if (file.isScript()) {
@@ -70,6 +70,7 @@ public class TypeHierarchyResolver {
this.descriptorResolver = descriptorResolver; this.descriptorResolver = descriptorResolver;
} }
// SCRIPT: inject script header resolver
@Inject @Inject
public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) { public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) {
this.scriptHeaderResolver = scriptHeaderResolver; this.scriptHeaderResolver = scriptHeaderResolver;
@@ -347,6 +348,7 @@ public class TypeHierarchyResolver {
c.getFileScopes().put(file, packageScope); c.getFileScopes().put(file, packageScope);
if (file.isScript()) { if (file.isScript()) {
// SCRIPT: process script hierarchy
scriptHeaderResolver.processScriptHierarchy(c, file.getScript(), packageScope); scriptHeaderResolver.processScriptHierarchy(c, file.getScript(), packageScope);
} }
@@ -60,6 +60,7 @@ public class DataFlowValueFactory {
@NotNull @NotNull
public static DataFlowValue createDataFlowValue(@NotNull ReceiverValue receiverValue, @NotNull BindingContext bindingContext) { public static DataFlowValue createDataFlowValue(@NotNull ReceiverValue receiverValue, @NotNull BindingContext bindingContext) {
if (receiverValue instanceof TransientReceiver || receiverValue instanceof ScriptReceiver) { if (receiverValue instanceof TransientReceiver || receiverValue instanceof ScriptReceiver) {
// SCRIPT: autocasts data flow
JetType type = receiverValue.getType(); JetType type = receiverValue.getType();
boolean nullable = type.isNullable() || TypeUtils.hasNullableSuperType(type); boolean nullable = type.isNullable() || TypeUtils.hasNullableSuperType(type);
return new DataFlowValue(receiverValue, type, nullable, Nullability.NOT_NULL); return new DataFlowValue(receiverValue, type, nullable, Nullability.NOT_NULL);
@@ -209,6 +209,7 @@ public class ExpressionTypingServices {
) { ) {
List<JetElement> block = expression.getStatements(); List<JetElement> block = expression.getStatements();
// SCRIPT: get code descriptor for script declaration
DeclarationDescriptor containingDescriptor = context.scope.getContainingDeclaration(); DeclarationDescriptor containingDescriptor = context.scope.getContainingDeclaration();
if (containingDescriptor instanceof ScriptDescriptor) { if (containingDescriptor instanceof ScriptDescriptor) {
if (!(expression.getParent() instanceof JetScript)) { if (!(expression.getParent() instanceof JetScript)) {
@@ -116,6 +116,7 @@ public class CodegenTestFiles {
List<AnalyzerScriptParameter> scriptParameterTypes = Lists.newArrayList(); List<AnalyzerScriptParameter> scriptParameterTypes = Lists.newArrayList();
List<Object> scriptParameterValues = Lists.newArrayList(); List<Object> scriptParameterValues = Lists.newArrayList();
// SCRIPT: extract script params, move to ScriptingUtil
if (file.isScript()) { if (file.isScript()) {
Pattern scriptParametersPattern = Pattern.compile("param: (\\S+): (\\S+): (\\S.*)"); Pattern scriptParametersPattern = Pattern.compile("param: (\\S+): (\\S+): (\\S.*)");
Matcher scriptParametersMatcher = scriptParametersPattern.matcher(file.getText()); Matcher scriptParametersMatcher = scriptParametersPattern.matcher(file.getText());
@@ -35,6 +35,7 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
// SCRIPT: Script declaration descriptor
public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl { public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
public static final String LAST_EXPRESSION_VALUE_FIELD_NAME = "rv"; public static final String LAST_EXPRESSION_VALUE_FIELD_NAME = "rv";
private static final Name NAME = Name.special("<script>"); private static final Name NAME = Name.special("<script>");
@@ -21,6 +21,7 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
// SCRIPT: script receiver
public class ScriptReceiver implements ThisReceiver { public class ScriptReceiver implements ThisReceiver {
@NotNull @NotNull
@@ -117,7 +117,7 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport
private static void forceResolvePackageDeclarations(@NotNull Collection<JetFile> files, @NotNull KotlinCodeAnalyzer session) { private static void forceResolvePackageDeclarations(@NotNull Collection<JetFile> files, @NotNull KotlinCodeAnalyzer session) {
for (JetFile file : files) { for (JetFile file : files) {
// Scripts are not supported // SCRIPT: not supported
if (file.isScript()) continue; if (file.isScript()) continue;
FqName packageFqName = file.getPackageFqName(); FqName packageFqName = file.getPackageFqName();