This commit is contained in:
@@ -22,5 +22,5 @@ package org.jetbrains.jet.cli.common;
|
||||
public class CompilerVersion {
|
||||
// The value of this constant is generated by the build script
|
||||
// DON'T MODIFY IT
|
||||
public static final String VERSION = "@snapshot@";
|
||||
public static final String VERSION = "snapshot";
|
||||
}
|
||||
|
||||
@@ -121,8 +121,8 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments, K2JSCompile
|
||||
@NotNull
|
||||
private static Config getConfig(@NotNull K2JSCompilerArguments arguments, @NotNull Project project) {
|
||||
if (arguments.libzip == null) {
|
||||
return Config.getEmptyConfig(project);
|
||||
return Config.getEmptyConfig(project, arguments.target);
|
||||
}
|
||||
return new ZippedLibrarySourcesConfig(project, arguments.libzip);
|
||||
return new ZippedLibrarySourcesConfig(project, arguments.libzip, arguments.target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ public class K2JSCompilerArguments extends CompilerArguments {
|
||||
@Argument(value = "srcdir", description = "Sources directory")
|
||||
public String srcdir;
|
||||
|
||||
@Argument(value = "target", description = "Generate js files for specific ECMA version (3 or 5, default ECMA 3)")
|
||||
public String target;
|
||||
|
||||
@Argument(value = "tags", description = "Demarcate each compilation message (error, warning, etc) with an open and close tag")
|
||||
public boolean tags;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.compiler.TranslatingCompiler;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Chunk;
|
||||
@@ -118,17 +119,33 @@ public final class K2JSCompiler implements TranslatingCompiler {
|
||||
context.addMessage(CompilerMessageCategory.ERROR, "K2JSCompiler does not support multiple module source roots.", null, -1, -1);
|
||||
return -1;
|
||||
}
|
||||
String[] commandLineArgs = constructArguments(context.getProject(), context.getModuleOutputDirectory(module), roots[0]);
|
||||
|
||||
VirtualFile outDir = context.getModuleOutputDirectory(module);
|
||||
String outFile = outDir == null ? null : K2JSRunnerUtils.constructPathToGeneratedFile(context.getProject(), outDir.getPath());
|
||||
|
||||
String[] commandLineArgs = constructArguments(context.getProject(), outFile, roots[0]);
|
||||
Object rc = invokeExecMethod(environment, out, context, commandLineArgs, "org.jetbrains.jet.cli.js.K2JSCompiler");
|
||||
|
||||
if (outDir != null) {
|
||||
outDir.refresh(false, true);
|
||||
}
|
||||
return CompilerUtils.getReturnCodeFromObject(rc);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] constructArguments(@NotNull Project project, @Nullable VirtualFile outDir, @NotNull VirtualFile srcDir) {
|
||||
private static String[] constructArguments(@NotNull Project project, @Nullable String outFile, @NotNull VirtualFile srcDir) {
|
||||
ArrayList<String> args = Lists.newArrayList("-tags", "-verbose", "-version");
|
||||
addPathToSourcesDir(args, srcDir);
|
||||
addOutputPath(project, outDir, args);
|
||||
addPathToZippedLib(project, args);
|
||||
addOutputPath(outFile, args);
|
||||
Pair<String, String> data = JsModuleDetector.getLibLocationAndTargetForProject(project);
|
||||
if (data.first != null) {
|
||||
args.add("-libzip");
|
||||
args.add(data.first);
|
||||
}
|
||||
if (data.second != null) {
|
||||
args.add("-target");
|
||||
args.add(data.second);
|
||||
}
|
||||
return ArrayUtil.toStringArray(args);
|
||||
}
|
||||
|
||||
@@ -138,23 +155,13 @@ public final class K2JSCompiler implements TranslatingCompiler {
|
||||
args.add(srcPath);
|
||||
}
|
||||
|
||||
private static void addOutputPath(@NotNull Project project, @Nullable VirtualFile outDir, @NotNull ArrayList<String> args) {
|
||||
if (outDir != null) {
|
||||
String outPath = outDir.getPath();
|
||||
String outFile = K2JSRunnerUtils.constructPathToGeneratedFile(project, outPath);
|
||||
private static void addOutputPath(@Nullable String outFile, @NotNull ArrayList<String> args) {
|
||||
if (outFile != null) {
|
||||
args.add("-output");
|
||||
args.add(outFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addPathToZippedLib(@NotNull Project project, @NotNull ArrayList<String> args) {
|
||||
String libLocationForProject = JsModuleDetector.getLibLocationForProject(project);
|
||||
if (libLocationForProject != null) {
|
||||
args.add("-libzip");
|
||||
args.add(libLocationForProject);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDescription() {
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.config.ZippedLibrarySourcesConfig;
|
||||
|
||||
import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationForProject;
|
||||
import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationAndTargetForProject;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -28,6 +28,6 @@ import static org.jetbrains.jet.plugin.project.JsModuleDetector.getLibLocationFo
|
||||
public final class IDEAConfig extends ZippedLibrarySourcesConfig {
|
||||
|
||||
public IDEAConfig(@NotNull Project project) {
|
||||
super(project, getLibLocationForProject(project));
|
||||
super(project, getLibLocationAndTargetForProject(project).first, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.plugin.project;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -60,42 +61,35 @@ public final class JsModuleDetector {
|
||||
}
|
||||
|
||||
//TODO: refactor
|
||||
@Nullable
|
||||
public static String getLibLocationForProject(@NotNull Project project) {
|
||||
@NotNull
|
||||
public static Pair<String, String> getLibLocationAndTargetForProject(@NotNull Project project) {
|
||||
VirtualFile indicationFile = findIndicationFileInContentRoots(project);
|
||||
if (indicationFile == null) {
|
||||
return null;
|
||||
return Pair.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream stream = indicationFile.getInputStream();
|
||||
String path = FileUtil.loadTextAndClose(stream);
|
||||
String pathToLibFile = getFirstLine(path);
|
||||
if (pathToLibFile == null) {
|
||||
return null;
|
||||
}
|
||||
BufferedReader reader = new BufferedReader(new StringReader(FileUtil.loadTextAndClose(stream)));
|
||||
try {
|
||||
String pathToLibFile = reader.readLine();
|
||||
if (pathToLibFile == null) {
|
||||
return Pair.empty();
|
||||
}
|
||||
|
||||
URI pathToLibFileUri = new URI(pathToLibFile);
|
||||
URI pathToIndicationFileUri = new URI(indicationFile.getPath());
|
||||
return pathToIndicationFileUri.resolve(pathToLibFileUri).toString();
|
||||
return new Pair<String, String>(pathToIndicationFileUri.resolve(pathToLibFileUri).toString(), reader.readLine());
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
return null;
|
||||
return Pair.empty();
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getFirstLine(@NotNull String path) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new StringReader(path));
|
||||
try {
|
||||
return reader.readLine();
|
||||
}
|
||||
|
||||
finally {
|
||||
reader.close();
|
||||
return Pair.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class TestConfig extends Config {
|
||||
private /*var*/ List<JetFile> jsLibFiles = null;
|
||||
|
||||
public TestConfig(@NotNull Project project) {
|
||||
super(project);
|
||||
super(project, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.k2js.config;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
@@ -25,6 +26,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.general.Translation.EcmaVersion;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
* <p/>
|
||||
@@ -33,8 +36,8 @@ import java.util.List;
|
||||
public abstract class Config {
|
||||
|
||||
@NotNull
|
||||
public static Config getEmptyConfig(@NotNull Project project) {
|
||||
return new Config(project) {
|
||||
public static Config getEmptyConfig(@NotNull Project project, @Nullable String target) {
|
||||
return new Config(project, target) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<JetFile> generateLibFiles() {
|
||||
@@ -67,9 +70,12 @@ public abstract class Config {
|
||||
private final Project project;
|
||||
@Nullable
|
||||
private List<JetFile> libFiles = null;
|
||||
@NotNull
|
||||
private final EcmaVersion target;
|
||||
|
||||
public Config(@NotNull Project project) {
|
||||
public Config(@NotNull Project project, @Nullable String target) {
|
||||
this.project = project;
|
||||
this.target = StringUtil.compareVersionNumbers(target, "5") >= 0 ? EcmaVersion.v5 : EcmaVersion.v3;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -77,6 +83,11 @@ public abstract class Config {
|
||||
return project;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public EcmaVersion getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract List<JetFile> generateLibFiles();
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ public class ZippedLibrarySourcesConfig extends Config {
|
||||
@Nullable
|
||||
protected final String pathToLibZip;
|
||||
|
||||
public ZippedLibrarySourcesConfig(@NotNull Project project, @Nullable String pathToZip) {
|
||||
super(project);
|
||||
public ZippedLibrarySourcesConfig(@NotNull Project project, @Nullable String pathToZip, @Nullable String target) {
|
||||
super(project, target);
|
||||
pathToLibZip = pathToZip;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,8 @@ public final class K2JSTranslator {
|
||||
JetStandardLibrary.initialize(config.getProject());
|
||||
BindingContext bindingContext = AnalyzerFacadeForJS.analyzeFilesAndCheckErrors(filesToTranslate, config);
|
||||
Collection<JetFile> files = AnalyzerFacadeForJS.withJsLibAdded(filesToTranslate, config);
|
||||
return Translation.generateAst(bindingContext, Lists.newArrayList(files), mainCallParameters);
|
||||
|
||||
return Translation.generateAst(bindingContext, Lists.newArrayList(files), mainCallParameters, config.getTarget());
|
||||
}
|
||||
|
||||
//TODO: util
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
@@ -44,7 +45,7 @@ import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*;
|
||||
public final class StaticContext {
|
||||
|
||||
public static StaticContext generateStaticContext(@NotNull JetStandardLibrary library,
|
||||
@NotNull BindingContext bindingContext) {
|
||||
@NotNull BindingContext bindingContext, Translation.EcmaVersion ecmaVersion) {
|
||||
JsProgram program = new JsProgram("main");
|
||||
JsRootScope jsRootScope = program.getRootScope();
|
||||
Namer namer = Namer.newInstance(jsRootScope);
|
||||
@@ -52,7 +53,7 @@ public final class StaticContext {
|
||||
Intrinsics intrinsics = Intrinsics.standardLibraryIntrinsics(library);
|
||||
StandardClasses standardClasses =
|
||||
StandardClasses.bindImplementations(namer.getKotlinScope());
|
||||
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, scope);
|
||||
return new StaticContext(program, bindingContext, namer, intrinsics, standardClasses, scope, ecmaVersion);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -83,17 +84,24 @@ public final class StaticContext {
|
||||
@NotNull
|
||||
private final Map<NamingScope, JsFunction> scopeToFunction = Maps.newHashMap();
|
||||
|
||||
@NotNull
|
||||
private final Translation.EcmaVersion ecmaVersion;
|
||||
|
||||
//TODO: too many parameters in constructor
|
||||
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
|
||||
@NotNull StandardClasses standardClasses, @NotNull NamingScope rootScope) {
|
||||
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
|
||||
@NotNull StandardClasses standardClasses, @NotNull NamingScope rootScope, @NotNull Translation.EcmaVersion ecmaVersion) {
|
||||
this.program = program;
|
||||
this.bindingContext = bindingContext;
|
||||
this.namer = namer;
|
||||
this.intrinsics = intrinsics;
|
||||
this.rootScope = rootScope;
|
||||
this.standardClasses = standardClasses;
|
||||
this.ecmaVersion = ecmaVersion;
|
||||
}
|
||||
|
||||
public boolean isEcma5() {
|
||||
return ecmaVersion == Translation.EcmaVersion.v5;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -219,8 +227,25 @@ public final class StaticContext {
|
||||
if (!(descriptor instanceof PropertyDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NamingScope enclosingScope = getEnclosingScope(descriptor);
|
||||
return enclosingScope.declareObfuscatableName(Namer.getKotlinBackingFieldName(descriptor.getName()));
|
||||
if (isEcma5()) {
|
||||
String name = descriptor.getName();
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
if (!isDefaultAccessor(propertyDescriptor.getGetter()) || !isDefaultAccessor(propertyDescriptor.getSetter())) {
|
||||
// _ is more preferable than $ — should be discussed later
|
||||
name = '_' + name;
|
||||
}
|
||||
|
||||
return enclosingScope.declareUnobfuscatableName(name);
|
||||
}
|
||||
else {
|
||||
return enclosingScope.declareObfuscatableName(Namer.getKotlinBackingFieldName(descriptor.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDefaultAccessor(PropertyAccessorDescriptor accessorDescriptor) {
|
||||
return accessorDescriptor == null || accessorDescriptor.isDefault();
|
||||
}
|
||||
};
|
||||
//TODO: hack!
|
||||
|
||||
@@ -54,6 +54,10 @@ public final class TranslationContext {
|
||||
rootDynamicContext, rootAliasingContext);
|
||||
}
|
||||
|
||||
public boolean isEcma5() {
|
||||
return staticContext.isEcma5();
|
||||
}
|
||||
|
||||
private TranslationContext(@NotNull StaticContext staticContext,
|
||||
@NotNull DynamicContext dynamicContext,
|
||||
@NotNull AliasingContext context) {
|
||||
|
||||
+1
-1
@@ -36,8 +36,8 @@ import org.jetbrains.k2js.translate.utils.ClassSortingUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClassesDefinedInNamespace;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getAllClassesDefinedInNamespace;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
|
||||
@@ -213,7 +213,10 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
if (!isTrait()) {
|
||||
propertyList.add(Translation.generateClassInitializerMethod(classDeclaration, classDeclarationContext));
|
||||
}
|
||||
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
|
||||
// skip for ecma5, because accessors defined via Object.defineProperties
|
||||
if (!context().isEcma5()) {
|
||||
propertyList.addAll(translatePropertiesAsConstructorParameters(classDeclarationContext));
|
||||
}
|
||||
propertyList.addAll(declarationBodyVisitor.traverseClass(classDeclaration, classDeclarationContext));
|
||||
return JsAstUtils.newObjectLiteral(propertyList);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyForDescriptor;
|
||||
@@ -53,6 +54,10 @@ public final class PropertyTranslator extends AbstractTranslator {
|
||||
|
||||
static public List<JsPropertyInitializer> translateAccessors(@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
if (context.isEcma5()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
PropertyTranslator propertyTranslator = new PropertyTranslator(descriptor, context);
|
||||
return propertyTranslator.translate();
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ import static org.jetbrains.k2js.translate.utils.dangerous.DangerousData.collect
|
||||
* Goal is to simlify interaction between translators.
|
||||
*/
|
||||
public final class Translation {
|
||||
public enum EcmaVersion {
|
||||
v3, v5
|
||||
}
|
||||
|
||||
private Translation() {
|
||||
}
|
||||
@@ -142,9 +145,9 @@ public final class Translation {
|
||||
|
||||
@NotNull
|
||||
public static JsProgram generateAst(@NotNull BindingContext bindingContext,
|
||||
@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters) throws TranslationException {
|
||||
@NotNull List<JetFile> files, @NotNull MainCallParameters mainCallParameters, EcmaVersion ecmaVersion) throws TranslationException {
|
||||
try {
|
||||
return doGenerateAst(bindingContext, files, mainCallParameters);
|
||||
return doGenerateAst(bindingContext, files, mainCallParameters, ecmaVersion);
|
||||
}
|
||||
catch (UnsupportedOperationException e) {
|
||||
throw new UnsupportedFeatureException("Unsupported feature used.", e);
|
||||
@@ -156,10 +159,10 @@ public final class Translation {
|
||||
|
||||
@NotNull
|
||||
private static JsProgram doGenerateAst(@NotNull BindingContext bindingContext, @NotNull List<JetFile> files,
|
||||
@NotNull MainCallParameters mainCallParameters) throws MainFunctionNotFoundException {
|
||||
@NotNull MainCallParameters mainCallParameters, EcmaVersion ecmaVersion) throws MainFunctionNotFoundException {
|
||||
//TODO: move some of the code somewhere
|
||||
JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
|
||||
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext);
|
||||
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext, ecmaVersion);
|
||||
JsBlock block = staticContext.getProgram().getFragmentBlock(0);
|
||||
TranslationContext context = TranslationContext.rootContext(staticContext);
|
||||
block.getStatements().addAll(translateFiles(files, context));
|
||||
|
||||
+19
-8
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -43,12 +44,13 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateArgum
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private final JetClassOrObject classDeclaration;
|
||||
@NotNull
|
||||
private final List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
|
||||
|
||||
private final JsObjectLiteral propertiesDefinition = new JsObjectLiteral();
|
||||
|
||||
public ClassInitializerTranslator(@NotNull JetClassOrObject classDeclaration, @NotNull TranslationContext context) {
|
||||
// Note: it's important we use scope for class descriptor because anonymous function used in property initializers
|
||||
// belong to the properties themselves
|
||||
@@ -65,8 +67,12 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
// for properties declared as constructor parameters
|
||||
setParameters(result, translatePrimaryConstructorParameters());
|
||||
mayBeAddCallToSuperMethod();
|
||||
initializerStatements.addAll((new InitializerVisitor()).traverseClass(classDeclaration, context()));
|
||||
initializerStatements.addAll((InitializerVisitor.create(context())).traverseClass(classDeclaration, context()));
|
||||
result.getBody().getStatements().addAll(initializerStatements);
|
||||
if (!propertiesDefinition.getPropertyInitializers().isEmpty()) {
|
||||
result.getBody().getStatements().add(JsAstUtils.defineProperties(propertiesDefinition));
|
||||
}
|
||||
|
||||
return InitializerUtils.generateInitializeMethod(result);
|
||||
}
|
||||
|
||||
@@ -123,15 +129,20 @@ public final class ClassInitializerTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private void mayBeAddInitializerStatementForProperty(@NotNull JsParameter jsParameter,
|
||||
@NotNull JetParameter jetParameter) {
|
||||
@NotNull JetParameter jetParameter) {
|
||||
PropertyDescriptor propertyDescriptor =
|
||||
getPropertyDescriptorForConstructorParameter(bindingContext(), jetParameter);
|
||||
if (propertyDescriptor != null) {
|
||||
JsStatement assignmentToBackingFieldExpression = assignmentToBackingField
|
||||
(context(), propertyDescriptor, jsParameter.getName().makeRef()).makeStmt();
|
||||
if (propertyDescriptor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final JsNameRef nameRef = jsParameter.getName().makeRef();
|
||||
if (context().isEcma5()) {
|
||||
propertiesDefinition.getPropertyInitializers().add(JsAstUtils.propertyDescriptor(propertyDescriptor, context(), nameRef));
|
||||
}
|
||||
else {
|
||||
JsStatement assignmentToBackingFieldExpression = assignmentToBackingField(context(), propertyDescriptor, nameRef).makeStmt();
|
||||
initializerStatements.add(assignmentToBackingFieldExpression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.k2js.translate.initializer;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
final class InitializerEcma5Visitor extends InitializerVisitor {
|
||||
private final JsObjectLiteral propertiesDefinition = new JsObjectLiteral();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JsExpression defineMember(TranslationContext context, PropertyDescriptor propertyDescriptor, JsExpression value) {
|
||||
propertiesDefinition.getPropertyInitializers().add(JsAstUtils.propertyDescriptor(propertyDescriptor, context, value));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<JsStatement> createStatements(List<JetDeclaration> declarations, TranslationContext context) {
|
||||
List<JsStatement> statements = super.createStatements(declarations, context);
|
||||
if (!propertiesDefinition.getPropertyInitializers().isEmpty()) {
|
||||
JsStatement statement = JsAstUtils.defineProperties(propertiesDefinition);
|
||||
if (statements.isEmpty()) {
|
||||
statements.add(statement);
|
||||
}
|
||||
else {
|
||||
statements.add(0, statement);
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
}
|
||||
+38
-35
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.initializer;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExprStmt;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -36,6 +34,7 @@ import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.general.Translation.translateAsStatement;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getDeclarationsForNamespace;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForObjectDeclaration;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationForName;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
|
||||
@@ -43,26 +42,25 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBa
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
|
||||
|
||||
/*package*/ InitializerVisitor() {
|
||||
class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
|
||||
static InitializerVisitor create(TranslationContext context) {
|
||||
return context.isEcma5() ? new InitializerEcma5Visitor() : new InitializerVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsStatement> visitProperty(@NotNull JetProperty expression, @NotNull TranslationContext context) {
|
||||
JetExpression initializer = expression.getInitializer();
|
||||
public final List<JsStatement> visitProperty(@NotNull JetProperty property, @NotNull TranslationContext context) {
|
||||
JetExpression initializer = property.getInitializer();
|
||||
if (initializer == null) {
|
||||
return new ArrayList<JsStatement>();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(translateInitializer(expression, context, initializer));
|
||||
return toStatements(defineMember(context, getPropertyDescriptor(context.bindingContext(), property),
|
||||
Translation.translateAsExpression(initializer, context)));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JsStatement translateInitializer(@NotNull JetProperty property, @NotNull TranslationContext context,
|
||||
@NotNull JetExpression initializer) {
|
||||
JsExpression initExpression = Translation.translateAsExpression(initializer, context);
|
||||
return assignmentToBackingField(context, property, initExpression).makeStmt();
|
||||
@Nullable
|
||||
protected JsExpression defineMember(TranslationContext context, PropertyDescriptor propertyDescriptor, JsExpression value) {
|
||||
return assignmentToBackingField(context, propertyDescriptor, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,32 +79,37 @@ public final class InitializerVisitor extends TranslatorVisitor<List<JsStatement
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<JsStatement> visitObjectDeclarationName(@NotNull JetObjectDeclarationName objectName,
|
||||
@NotNull TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptorForObjectDeclaration
|
||||
= getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
|
||||
public final List<JsStatement> visitObjectDeclarationName(@NotNull JetObjectDeclarationName objectName,
|
||||
@NotNull TranslationContext context) {
|
||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptorForObjectDeclaration(context.bindingContext(), objectName);
|
||||
JetObjectDeclaration objectDeclaration = getObjectDeclarationForName(objectName);
|
||||
JsInvocation objectValue = ClassTranslator.generateClassCreationExpression(objectDeclaration, context);
|
||||
JsExprStmt assignment = assignmentToBackingField(context, propertyDescriptorForObjectDeclaration, objectValue)
|
||||
.makeStmt();
|
||||
return Collections.<JsStatement>singletonList(assignment);
|
||||
return toStatements(defineMember(context, propertyDescriptor, objectValue));
|
||||
}
|
||||
|
||||
private static List<JsStatement> toStatements(@Nullable JsExpression expression) {
|
||||
return expression == null ? Collections.<JsStatement>emptyList() : Collections.<JsStatement>singletonList(expression.makeStmt());
|
||||
}
|
||||
|
||||
protected List<JsStatement> createStatements(List<JetDeclaration> declarations, TranslationContext context) {
|
||||
if (declarations.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<JsStatement> statements = new ArrayList<JsStatement>(declarations.size());
|
||||
for (JetDeclaration declaration : declarations) {
|
||||
statements.addAll(declaration.accept(this, context));
|
||||
}
|
||||
return statements;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsStatement> traverseClass(@NotNull JetClassOrObject expression, @NotNull TranslationContext context) {
|
||||
List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
|
||||
for (JetDeclaration declaration : expression.getDeclarations()) {
|
||||
initializerStatements.addAll(declaration.accept(this, context));
|
||||
}
|
||||
return initializerStatements;
|
||||
public final List<JsStatement> traverseClass(@NotNull JetClassOrObject expression, @NotNull TranslationContext context) {
|
||||
return createStatements(expression.getDeclarations(), context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JsStatement> traverseNamespace(@NotNull NamespaceDescriptor namespace, @NotNull TranslationContext context) {
|
||||
List<JsStatement> initializerStatements = new ArrayList<JsStatement>();
|
||||
for (JetDeclaration declaration : getDeclarationsForNamespace(context.bindingContext(), namespace)) {
|
||||
initializerStatements.addAll(declaration.accept(this, context));
|
||||
}
|
||||
return initializerStatements;
|
||||
public final List<JsStatement> traverseNamespace(@NotNull NamespaceDescriptor namespace, @NotNull TranslationContext context) {
|
||||
return createStatements(getDeclarationsForNamespace(context.bindingContext(), namespace), context);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-5
@@ -46,11 +46,10 @@ public final class NamespaceInitializerTranslator {
|
||||
JsFunction result = JsAstUtils.createFunctionWithEmptyBody(namespaceContext.jsScope());
|
||||
TranslationContext namespaceInitializerContext
|
||||
= namespaceContext.innerContextWithGivenScopeAndBlock(result.getScope(), result.getBody());
|
||||
List<JsStatement> initializerStatements =
|
||||
(new InitializerVisitor()).traverseNamespace(namespace, namespaceInitializerContext);
|
||||
|
||||
List<JsStatement> initializerStatements = (InitializerVisitor.create(namespaceContext)).traverseNamespace(namespace,
|
||||
namespaceInitializerContext);
|
||||
result.getBody().getStatements().addAll(initializerStatements);
|
||||
return InitializerUtils.generateInitializeMethod(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,7 @@ import com.google.dart.compiler.backend.js.ast.JsNew;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
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.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall;
|
||||
@@ -238,6 +236,17 @@ public final class CallTranslator extends AbstractTranslator {
|
||||
if (receiver != null) {
|
||||
setQualifier(callee, receiver);
|
||||
}
|
||||
|
||||
if (context().isEcma5()) {
|
||||
if (descriptor instanceof PropertyGetterDescriptor) {
|
||||
return callee;
|
||||
}
|
||||
else if (descriptor instanceof PropertySetterDescriptor) {
|
||||
assert arguments.size() == 1;
|
||||
return assignment(callee, arguments.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
return newInvocation(callee, arguments);
|
||||
}
|
||||
}, context());
|
||||
|
||||
+4
-5
@@ -20,14 +20,13 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedThisDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.qualified;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedThisDescriptor;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -73,7 +72,7 @@ public final class NativePropertyAccessTranslator extends PropertyAccessTranslat
|
||||
@NotNull
|
||||
protected JsExpression translateAsSet(@Nullable JsExpression receiver, @NotNull JsExpression setTo) {
|
||||
assert receiver != null;
|
||||
return assignment(translateAsGet(getReceiver()), setTo);
|
||||
return assignment(translateAsGet(receiver), setTo);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -83,7 +82,7 @@ public final class NativePropertyAccessTranslator extends PropertyAccessTranslat
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsExpression getReceiver() {
|
||||
private JsExpression getReceiver() {
|
||||
if (receiver != null) {
|
||||
return receiver;
|
||||
}
|
||||
|
||||
+9
-2
@@ -21,6 +21,7 @@ import com.google.dart.compiler.backend.js.ast.JsName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
@@ -55,8 +56,14 @@ public final class ReferenceTranslator {
|
||||
@NotNull
|
||||
public static JsExpression translateAsLocalNameReference(@NotNull DeclarationDescriptor referencedDescriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
JsName referencedName = context.getNameForDescriptor(referencedDescriptor);
|
||||
return referencedName.makeRef();
|
||||
DeclarationDescriptor effectiveDescriptor;
|
||||
if (context.isEcma5() && referencedDescriptor instanceof PropertyAccessorDescriptor) {
|
||||
effectiveDescriptor = ((PropertyAccessorDescriptor) referencedDescriptor).getCorrespondingProperty();
|
||||
}
|
||||
else {
|
||||
effectiveDescriptor = referencedDescriptor;
|
||||
}
|
||||
return context.getNameForDescriptor(effectiveDescriptor).makeRef();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,6 +20,9 @@ import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -27,6 +30,16 @@ import java.util.*;
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class JsAstUtils {
|
||||
private static final JsNameRef VALUE = new JsNameRef("value");
|
||||
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(new JsNameRef("writable"), null) ;
|
||||
private static final JsNameRef DEFINE_PROPERTIES = new JsNameRef("defineProperties");
|
||||
private static final JsNameRef CREATE = new JsNameRef("create");
|
||||
|
||||
static {
|
||||
JsNameRef nameRef = new JsNameRef("Object");
|
||||
DEFINE_PROPERTIES.setQualifier(nameRef);
|
||||
CREATE.setQualifier(nameRef);
|
||||
}
|
||||
|
||||
private JsAstUtils() {
|
||||
}
|
||||
@@ -272,4 +285,38 @@ public final class JsAstUtils {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsStatement defineProperties(JsObjectLiteral propertiesDefinition) {
|
||||
JsInvocation invoke = new JsInvocation();
|
||||
invoke.setQualifier(DEFINE_PROPERTIES);
|
||||
invoke.getArguments().add(new JsThisRef());
|
||||
invoke.getArguments().add(propertiesDefinition);
|
||||
return invoke.makeStmt();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsPropertyInitializer propertyDescriptor(PropertyDescriptor ktDescriptor,
|
||||
TranslationContext context,
|
||||
JsExpression value) {
|
||||
return propertyDescriptor(ktDescriptor, context, value, ktDescriptor.isVar());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsPropertyInitializer propertyDescriptor(DeclarationDescriptor ktDescriptor,
|
||||
TranslationContext context,
|
||||
JsExpression value,
|
||||
boolean writable) {
|
||||
JsObjectLiteral descriptor = new JsObjectLiteral();
|
||||
List<JsPropertyInitializer> meta = descriptor.getPropertyInitializers();
|
||||
meta.add(new JsPropertyInitializer(VALUE, value));
|
||||
if (writable) {
|
||||
if (WRITABLE.getValueExpr() == null) {
|
||||
WRITABLE.setValueExpr(context.program().getTrueLiteral());
|
||||
}
|
||||
meta.add(WRITABLE);
|
||||
}
|
||||
// todo accessors
|
||||
return new JsPropertyInitializer(context.getNameForDescriptor(ktDescriptor).makeRef(), descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,9 @@ import java.util.List;
|
||||
|
||||
import static com.google.dart.compiler.util.AstUtil.newAssignment;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getDeclarationDescriptorForReceiver;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -204,13 +203,6 @@ public final class TranslationUtils {
|
||||
return intrinsic.apply(left, Arrays.asList(right), context);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression assignmentToBackingField(@NotNull TranslationContext context, @NotNull JetProperty property,
|
||||
@NotNull JsExpression initExpression) {
|
||||
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(context.bindingContext(), property);
|
||||
return assignmentToBackingField(context, propertyDescriptor, initExpression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static JsExpression resolveThisObjectForResolvedCall(@NotNull ResolvedCall<?> call,
|
||||
@NotNull TranslationContext context) {
|
||||
@@ -219,6 +211,6 @@ public final class TranslationUtils {
|
||||
return null;
|
||||
}
|
||||
DeclarationDescriptor expectedThisDescriptor = getDeclarationDescriptorForReceiver(thisObject);
|
||||
return TranslationUtils.getThisObject(context, expectedThisDescriptor);
|
||||
return getThisObject(context, expectedThisDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user