Merge branch 'master' of github.com:JetBrains/kotlin
This commit is contained in:
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.lang.Configuration;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
@@ -112,21 +111,12 @@ public class JetDiagnosticsTest extends JetLiteFixture {
|
||||
}
|
||||
});
|
||||
|
||||
boolean importJdk = expectedText.contains("+JDK");
|
||||
// Configuration configuration = importJdk ? JavaBridgeConfiguration.createJavaBridgeConfiguration(getProject()) : Configuration.EMPTY;
|
||||
|
||||
List<JetFile> jetFiles = Lists.newArrayList();
|
||||
for (TestFile testFileFile : testFileFiles) {
|
||||
jetFiles.add(testFileFile.jetFile);
|
||||
}
|
||||
|
||||
BindingContext bindingContext;
|
||||
if (importJdk) {
|
||||
bindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
}
|
||||
else {
|
||||
bindingContext = AnalyzingUtils.analyzeFiles(getProject(), Configuration.EMPTY, jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
}
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
|
||||
@@ -70,8 +70,6 @@ public final class AnalyzerFacade {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: use some mechanism to avoid this
|
||||
//TODO: move method somewhere
|
||||
@NotNull
|
||||
public static List<JetFile> withJsLibAdded(@NotNull List<JetFile> files, @NotNull Config config) {
|
||||
List<JetFile> allFiles = new ArrayList<JetFile>();
|
||||
|
||||
@@ -21,13 +21,13 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
import org.jetbrains.k2js.translate.context.generator.Generator;
|
||||
import org.jetbrains.k2js.translate.context.generator.Rule;
|
||||
import org.jetbrains.k2js.translate.intrinsic.Intrinsics;
|
||||
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
|
||||
import org.jetbrains.k2js.translate.utils.PredefinedAnnotation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -90,7 +90,7 @@ public final class StaticContext {
|
||||
private final Map<NamingScope, JsFunction> scopeToFunction = Maps.newHashMap();
|
||||
|
||||
|
||||
//TODO: too many parameters in constructor
|
||||
//qTODO: too many parameters in constructor
|
||||
private StaticContext(@NotNull JsProgram program, @NotNull BindingContext bindingContext,
|
||||
@NotNull Aliaser aliaser,
|
||||
@NotNull Namer namer, @NotNull Intrinsics intrinsics,
|
||||
@@ -217,24 +217,15 @@ public final class StaticContext {
|
||||
}
|
||||
};
|
||||
|
||||
Rule<JsName> namesAnnotatedAsLibraryHasUnobfuscatableNames = new Rule<JsName>() {
|
||||
Rule<JsName> predefinedObjectsHasUnobfuscatableNames = new Rule<JsName>() {
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
//TODO: refactor
|
||||
String name = null;
|
||||
AnnotationDescriptor annotation = getAnnotationByName(descriptor, LIBRARY_ANNOTATION_FQNAME);
|
||||
if (annotation != null) {
|
||||
name = AnnotationsUtils.getAnnotationStringParameter(descriptor, LIBRARY_ANNOTATION_FQNAME);
|
||||
name = (!name.isEmpty()) ? name : descriptor.getName();
|
||||
}
|
||||
else {
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) return null;
|
||||
if (getAnnotationByName(containingClass, LIBRARY_ANNOTATION_FQNAME) != null) {
|
||||
name = descriptor.getName();
|
||||
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
|
||||
if (!hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (name != null) {
|
||||
String name = getNameForAnnotatedObject(descriptor, annotation);
|
||||
name = (name != null) ? name : descriptor.getName();
|
||||
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
|
||||
}
|
||||
return null;
|
||||
@@ -267,29 +258,7 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
};
|
||||
Rule<JsName> namesForNativeObjectsAreUnobfuscatable = new Rule<JsName>() {
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
String name = null;
|
||||
AnnotationDescriptor annotation = getAnnotationByName(descriptor, NATIVE_ANNOTATION_FQNAME);
|
||||
if (annotation != null) {
|
||||
name = AnnotationsUtils.getAnnotationStringParameter(descriptor, NATIVE_ANNOTATION_FQNAME);
|
||||
name = (!name.isEmpty()) ? name : descriptor.getName();
|
||||
}
|
||||
else {
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) return null;
|
||||
if (getAnnotationByName(containingClass, NATIVE_ANNOTATION_FQNAME) != null) {
|
||||
name = descriptor.getName();
|
||||
}
|
||||
}
|
||||
if (name != null) {
|
||||
return getEnclosingScope(descriptor).declareUnobfuscatableName(name);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
};
|
||||
Rule<JsName> overridingDescriptorsReferToOriginalName = new Rule<JsName>() {
|
||||
@Override
|
||||
public JsName apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
@@ -302,9 +271,7 @@ public final class StaticContext {
|
||||
else {
|
||||
//assert overriddenDescriptors.size() == 1;
|
||||
//TODO: for now translator can't deal with multiple inheritance good enough
|
||||
for (FunctionDescriptor overriddenDescriptor : overriddenDescriptors) {
|
||||
return getNameForDescriptor(overriddenDescriptor);
|
||||
}
|
||||
return getNameForDescriptor(overriddenDescriptors.iterator().next());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -312,8 +279,7 @@ public final class StaticContext {
|
||||
};
|
||||
addRule(namesForStandardClasses);
|
||||
addRule(constructorHasTheSameNameAsTheClass);
|
||||
addRule(namesAnnotatedAsLibraryHasUnobfuscatableNames);
|
||||
addRule(namesForNativeObjectsAreUnobfuscatable);
|
||||
addRule(predefinedObjectsHasUnobfuscatableNames);
|
||||
addRule(toStringHack);
|
||||
addRule(propertiesCorrespondToSpeciallyTreatedBackingFieldNames);
|
||||
addRule(namespacesShouldBeDefinedInRootScope);
|
||||
@@ -440,27 +406,13 @@ public final class StaticContext {
|
||||
|
||||
@Override
|
||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (getAnnotationByName(descriptor, AnnotationsUtils.LIBRARY_ANNOTATION_FQNAME) != null) {
|
||||
return namer.kotlinObject();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Rule<JsNameRef> membersOfAnnotatedClassesHaveKotlinQualifier = new Rule<JsNameRef>() {
|
||||
@Override
|
||||
public JsNameRef apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) {
|
||||
return null;
|
||||
}
|
||||
if (getAnnotationByName(descriptor, LIBRARY_ANNOTATION_FQNAME) != null) {
|
||||
if (isLibraryObject(descriptor)) {
|
||||
return namer.kotlinObject();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
addRule(libraryObjectsHaveKotlinQualifier);
|
||||
addRule(membersOfAnnotatedClassesHaveKotlinQualifier);
|
||||
addRule(constructorHaveTheSameQualifierAsTheClass);
|
||||
addRule(namespacesHaveNoQualifiers);
|
||||
addRule(namespaceLevelDeclarationsHaveEnclosingNamespacesNamesAsQualifier);
|
||||
|
||||
@@ -35,8 +35,8 @@ import org.jetbrains.k2js.translate.operation.IncrementTranslator;
|
||||
import org.jetbrains.k2js.translate.operation.UnaryOperationTranslator;
|
||||
import org.jetbrains.k2js.translate.reference.*;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -44,6 +44,7 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getObjectDeclarationName;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateInitializerForProperty;
|
||||
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -161,10 +162,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
return ifStatement;
|
||||
}
|
||||
TemporaryVariable result = context.declareTemporary(context.program().getNullLiteral());
|
||||
JsAstUtils.SaveLastExpressionMutator saveResultToTemporaryMutator =
|
||||
new JsAstUtils.SaveLastExpressionMutator(result.reference());
|
||||
JsNode mutatedIfStatement = mutateLastExpression(ifStatement,
|
||||
saveResultToTemporaryMutator);
|
||||
AssignToExpressionMutator saveResultToTemporaryMutator =
|
||||
new AssignToExpressionMutator(result.reference());
|
||||
JsNode mutatedIfStatement = mutateLastExpression(ifStatement, saveResultToTemporaryMutator);
|
||||
JsStatement resultingStatement = convertToStatement(mutatedIfStatement);
|
||||
context.addStatementToCurrentBlock(resultingStatement);
|
||||
return result.reference();
|
||||
|
||||
+8
-17
@@ -21,7 +21,9 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.k2js.translate.context.Namer;
|
||||
@@ -30,16 +32,18 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.utils.DescriptorUtils;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.mutator.Mutator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.setParameters;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.newAliasForThis;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.removeAliasForThis;
|
||||
import static org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator.mutateLastExpression;
|
||||
|
||||
|
||||
/**
|
||||
@@ -128,15 +132,7 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsFunction createFunctionObject() {
|
||||
// if (isDeclaration()) {
|
||||
return context().getFunctionObject(descriptor);
|
||||
// }
|
||||
// if (isLiteral()) {
|
||||
// //TODO: changing this piece of code to more natural "same as for declaration" results in life test failing
|
||||
// //TODO: must investigate
|
||||
// return new JsFunction(context().jsScope());
|
||||
// }
|
||||
// throw new AssertionError("Unsupported type of functionDeclaration.");
|
||||
}
|
||||
|
||||
private void translateBody() {
|
||||
@@ -164,7 +160,7 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
}
|
||||
|
||||
private static JsNode lastExpressionReturned(@NotNull JsNode body) {
|
||||
return mutateLastExpression(body, new JsAstUtils.Mutator() {
|
||||
return mutateLastExpression(body, new Mutator() {
|
||||
@Override
|
||||
@NotNull
|
||||
public JsNode mutate(@NotNull JsNode node) {
|
||||
@@ -219,9 +215,4 @@ public final class FunctionTranslator extends AbstractTranslator {
|
||||
private boolean isLiteral() {
|
||||
return functionDeclaration instanceof JetFunctionLiteralExpression;
|
||||
}
|
||||
|
||||
private boolean isDeclaration() {
|
||||
return (functionDeclaration instanceof JetNamedFunction) ||
|
||||
(functionDeclaration instanceof JetPropertyAccessor);
|
||||
}
|
||||
}
|
||||
|
||||
+26
-25
@@ -22,6 +22,7 @@ import com.google.dart.compiler.backend.js.ast.JsName;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -31,6 +32,8 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPattern;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getTypeReference;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
@@ -57,14 +60,6 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return resultingExpression;
|
||||
}
|
||||
|
||||
//TODO: inspection
|
||||
@NotNull
|
||||
private JetPattern getPattern(@NotNull JetIsExpression expression) {
|
||||
JetPattern pattern = expression.getPattern();
|
||||
assert pattern != null : "Pattern should not be null";
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression translatePattern(@NotNull JetPattern pattern, @NotNull JsExpression expressionToMatch) {
|
||||
if (pattern instanceof JetTypePattern) {
|
||||
@@ -79,15 +74,16 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
private JsExpression translateTypePattern(@NotNull JsExpression expressionToMatch,
|
||||
@NotNull JetTypePattern pattern) {
|
||||
//TODO: look into using intrinsics or other mechanisms to implement this logic
|
||||
JsName className = getClassReference(pattern).getName();
|
||||
if (className.getIdent().equals("String")) {
|
||||
return typeof(expressionToMatch, program().getStringLiteral("string"));
|
||||
}
|
||||
if (className.getIdent().equals("Int")) {
|
||||
return typeof(expressionToMatch, program().getStringLiteral("number"));
|
||||
JsExpression result = translateAsIntrinsicTypeCheck(expressionToMatch, pattern);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
return translateAsIsCheck(expressionToMatch, pattern);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression translateAsIsCheck(@NotNull JsExpression expressionToMatch,
|
||||
@NotNull JetTypePattern pattern) {
|
||||
JsInvocation isCheck = AstUtil.newInvocation(context().namer().isOperationReference(),
|
||||
expressionToMatch, getClassReference(pattern));
|
||||
if (isNullable(pattern)) {
|
||||
@@ -96,14 +92,27 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return isCheck;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JsExpression translateAsIntrinsicTypeCheck(@NotNull JsExpression expressionToMatch,
|
||||
@NotNull JetTypePattern pattern) {
|
||||
JsExpression result = null;
|
||||
JsName className = getClassReference(pattern).getName();
|
||||
if (className.getIdent().equals("String")) {
|
||||
result = typeof(expressionToMatch, program().getStringLiteral("string"));
|
||||
}
|
||||
if (className.getIdent().equals("Int")) {
|
||||
result = typeof(expressionToMatch, program().getStringLiteral("number"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression addNullCheck(@NotNull JsExpression expressionToMatch, @NotNull JsInvocation isCheck) {
|
||||
return or(TranslationUtils.isNullCheck(context(), expressionToMatch), isCheck);
|
||||
}
|
||||
|
||||
private boolean isNullable(JetTypePattern pattern) {
|
||||
return BindingUtils.getTypeByReference(bindingContext(),
|
||||
getTypeReference(pattern)).isNullable();
|
||||
return BindingUtils.getTypeByReference(bindingContext(), getTypeReference(pattern)).isNullable();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -112,14 +121,6 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return getClassNameReferenceForTypeReference(typeReference);
|
||||
}
|
||||
|
||||
//TODO: inspection: util?
|
||||
@NotNull
|
||||
private JetTypeReference getTypeReference(@NotNull JetTypePattern pattern) {
|
||||
JetTypeReference typeReference = pattern.getTypeReference();
|
||||
assert typeReference != null : "Type pattern should contain a type reference";
|
||||
return typeReference;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNameRef getClassNameReferenceForTypeReference(@NotNull JetTypeReference typeReference) {
|
||||
ClassDescriptor referencedClass = BindingUtils.getClassDescriptorForTypeReference
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.k2js.translate.general.Translation;
|
||||
import org.jetbrains.k2js.translate.utils.JsAstUtils;
|
||||
import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator;
|
||||
import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -121,8 +122,8 @@ public class WhenTranslator extends AbstractTranslator {
|
||||
@NotNull
|
||||
JsStatement withReturnValueCaptured(@NotNull JsNode node) {
|
||||
|
||||
return convertToStatement(mutateLastExpression(node,
|
||||
new JsAstUtils.SaveLastExpressionMutator(result.reference())));
|
||||
return convertToStatement(LastExpressionMutator.mutateLastExpression(node,
|
||||
new AssignToExpressionMutator(result.reference())));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
-1
@@ -31,7 +31,6 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||
|
||||
-2
@@ -31,8 +31,6 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopParameter;
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
|
||||
//TODO: create util class for managing stuff like binary operations
|
||||
public abstract class ForTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
|
||||
-1
@@ -29,7 +29,6 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
|
||||
import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getClassDescriptorForType;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||
|
||||
-1
@@ -27,7 +27,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.*;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
||||
|
||||
@@ -116,7 +116,7 @@ public final class Translation {
|
||||
StaticContext staticContext = StaticContext.generateStaticContext(standardLibrary, bindingContext);
|
||||
JsBlock block = staticContext.getProgram().getFragmentBlock(0);
|
||||
TranslationContext context = TranslationContext.rootContext(staticContext);
|
||||
block.getStatements().addAll(Translation.translateFiles(files, context));
|
||||
block.getStatements().addAll(translateFiles(files, context));
|
||||
JsNamer namer = new JsPrettyNamer();
|
||||
namer.exec(context.program());
|
||||
return context.program();
|
||||
|
||||
@@ -31,46 +31,48 @@ import static org.jetbrains.k2js.translate.utils.DescriptorUtils.getContainingCl
|
||||
*/
|
||||
public final class AnnotationsUtils {
|
||||
|
||||
@NotNull
|
||||
public static final String NATIVE_ANNOTATION_FQNAME = "js.native";
|
||||
@NotNull
|
||||
public static final String LIBRARY_ANNOTATION_FQNAME = "js.library";
|
||||
|
||||
private AnnotationsUtils() {
|
||||
}
|
||||
|
||||
//TODO: make public, use when necessary
|
||||
private static boolean hasAnnotation(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull String annotationFQNAme) {
|
||||
return getAnnotationByName(descriptor, annotationFQNAme) != null;
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
return getAnnotationByName(descriptor, annotation) != null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
public static String getAnnotationStringParameter(@NotNull DeclarationDescriptor declarationDescriptor,
|
||||
@NotNull String annotationFQName) {
|
||||
AnnotationDescriptor annotationDescriptor =
|
||||
getAnnotationByName(declarationDescriptor, annotationFQName);
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
AnnotationDescriptor annotationDescriptor = getAnnotationByName(declarationDescriptor, annotation);
|
||||
assert annotationDescriptor != null;
|
||||
//TODO: this is a quick fix for unsupported default args problem
|
||||
if (annotationDescriptor.getValueArguments().isEmpty()) {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
CompileTimeConstant<?> constant = annotationDescriptor.getValueArguments().iterator().next();
|
||||
//TODO: this is a quick fix for unsupported default args problem
|
||||
if (constant == null) {
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
Object value = constant.getValue();
|
||||
assert value instanceof String : "Native function annotation should have one String parameter";
|
||||
return (String) value;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getNameForAnnotatedObject(@NotNull DeclarationDescriptor declarationDescriptor,
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
if (!hasAnnotation(declarationDescriptor, annotation)) {
|
||||
return null;
|
||||
}
|
||||
return getAnnotationStringParameter(declarationDescriptor, annotation);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull String FQName) {
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
|
||||
String annotationClassFQName = getAnnotationClassFQName(annotationDescriptor);
|
||||
if (annotationClassFQName.equals(FQName)) {
|
||||
if (annotationClassFQName.equals(annotation.getFQName())) {
|
||||
return annotationDescriptor;
|
||||
}
|
||||
}
|
||||
@@ -86,26 +88,31 @@ public final class AnnotationsUtils {
|
||||
}
|
||||
|
||||
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, NATIVE_ANNOTATION_FQNAME);
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.NATIVE);
|
||||
}
|
||||
|
||||
public static boolean isLibraryObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, LIBRARY_ANNOTATION_FQNAME);
|
||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, PredefinedAnnotation.LIBRARY);
|
||||
}
|
||||
|
||||
//TODO: the use of this method is splattered across the code which can be hard to track
|
||||
public static boolean isPredefinedObject(@NotNull DeclarationDescriptor descriptor) {
|
||||
return isLibraryObject(descriptor) || isNativeObject(descriptor);
|
||||
for (PredefinedAnnotation annotation : PredefinedAnnotation.values()) {
|
||||
if (hasAnnotationOrInsideAnnotatedClass(descriptor, annotation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasAnnotationOrInsideAnnotatedClass(DeclarationDescriptor descriptor, String annotationFQName) {
|
||||
if (getAnnotationByName(descriptor, annotationFQName) != null) {
|
||||
public static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull PredefinedAnnotation annotation) {
|
||||
if (getAnnotationByName(descriptor, annotation) != null) {
|
||||
return true;
|
||||
}
|
||||
ClassDescriptor containingClass = getContainingClass(descriptor);
|
||||
if (containingClass == null) {
|
||||
return false;
|
||||
}
|
||||
return (getAnnotationByName(containingClass, annotationFQName) != null);
|
||||
return (getAnnotationByName(containingClass, annotation) != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public final class BindingUtils {
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
continue;
|
||||
}
|
||||
JetDeclaration declaration = BindingUtils.getDeclarationForDescriptor(bindingContext, descriptor);
|
||||
JetDeclaration declaration = getDeclarationForDescriptor(bindingContext, descriptor);
|
||||
if (declaration != null) {
|
||||
declarations.add(declaration);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ 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.k2js.translate.context.TemporaryVariable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -88,12 +89,6 @@ public final class JsAstUtils {
|
||||
return convertToStatement(new JsBinaryOperation(JsBinaryOperator.ASG, nameRef, expr));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression extractExpressionFromStatement(@NotNull JsStatement statement) {
|
||||
assert statement instanceof JsExprStmt : "Cannot extract expression from statement: " + statement;
|
||||
return (((JsExprStmt) statement).getExpression());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsBinaryOperation and(@NotNull JsExpression op1, @NotNull JsExpression op2) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.AND, op1, op2);
|
||||
@@ -104,24 +99,23 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
|
||||
}
|
||||
|
||||
//TODO refactor
|
||||
public static void setQualifier(@NotNull JsExpression selector, @Nullable JsExpression receiver) {
|
||||
assert (selector instanceof JsInvocation || selector instanceof JsNameRef);
|
||||
if (selector instanceof JsInvocation) {
|
||||
setQualifier(((JsInvocation) selector).getQualifier(), receiver);
|
||||
return;
|
||||
}
|
||||
if (selector instanceof JsNameRef) {
|
||||
JsNameRef nameRef = (JsNameRef) selector;
|
||||
JsExpression qualifier = nameRef.getQualifier();
|
||||
if (qualifier == null) {
|
||||
nameRef.setQualifier(receiver);
|
||||
}
|
||||
else {
|
||||
setQualifier(qualifier, receiver);
|
||||
}
|
||||
return;
|
||||
setQualifierForNameRef((JsNameRef) selector, receiver);
|
||||
}
|
||||
|
||||
private static void setQualifierForNameRef(@NotNull JsNameRef selector, @Nullable JsExpression receiver) {
|
||||
JsExpression qualifier = selector.getQualifier();
|
||||
if (qualifier == null) {
|
||||
selector.setQualifier(receiver);
|
||||
}
|
||||
else {
|
||||
setQualifier(qualifier, receiver);
|
||||
}
|
||||
throw new AssertionError("Set qualifier should be applied only to JsInvocation or JsNameRef instances");
|
||||
}
|
||||
|
||||
public static JsNameRef qualified(@NotNull JsName selector, @Nullable JsExpression qualifier) {
|
||||
@@ -140,11 +134,6 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.NEQ, arg1, arg2);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression equalsTrue(@NotNull JsExpression expression, @NotNull JsProgram program) {
|
||||
return equality(expression, program.getTrueLiteral());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression assignment(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return new JsBinaryOperation(JsBinaryOperator.ASG, left, right);
|
||||
@@ -205,60 +194,6 @@ public final class JsAstUtils {
|
||||
return jsObjectLiteral;
|
||||
}
|
||||
|
||||
public interface Mutator {
|
||||
JsNode mutate(JsNode node);
|
||||
}
|
||||
|
||||
|
||||
//TODO: move somewhere
|
||||
//TODO: refactor and review
|
||||
public static JsNode mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
|
||||
if (node instanceof JsBlock) {
|
||||
JsBlock block = (JsBlock) node;
|
||||
List<JsStatement> statements = block.getStatements();
|
||||
|
||||
if (statements.isEmpty()) return block;
|
||||
|
||||
int size = statements.size();
|
||||
statements.set(size - 1,
|
||||
convertToStatement(mutateLastExpression(statements.get(size - 1), mutator)));
|
||||
return block;
|
||||
}
|
||||
if (node instanceof JsIf) {
|
||||
JsIf ifExpr = (JsIf) node;
|
||||
ifExpr.setThenStmt(convertToStatement(mutateLastExpression(ifExpr.getThenStmt(), mutator)));
|
||||
JsStatement elseStmt = ifExpr.getElseStmt();
|
||||
if (elseStmt != null) {
|
||||
ifExpr.setElseStmt(convertToStatement(mutateLastExpression(elseStmt, mutator)));
|
||||
}
|
||||
return ifExpr;
|
||||
}
|
||||
if (node instanceof JsExprStmt) {
|
||||
return convertToStatement(mutateLastExpression(((JsExprStmt) node).getExpression(), mutator));
|
||||
}
|
||||
return mutator.mutate(node);
|
||||
}
|
||||
|
||||
|
||||
public static final class SaveLastExpressionMutator implements Mutator {
|
||||
|
||||
@NotNull
|
||||
private final JsExpression toAssign;
|
||||
|
||||
public SaveLastExpressionMutator(@NotNull JsExpression toAssign) {
|
||||
this.toAssign = toAssign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsNode mutate(JsNode node) {
|
||||
if (!(node instanceof JsExpression)) {
|
||||
return node;
|
||||
}
|
||||
return assignment(toAssign, (JsExpression) node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static JsVars newVar(@NotNull JsName name, @Nullable JsExpression expr) {
|
||||
JsVars.JsVar var = new JsVars.JsVar(name);
|
||||
@@ -288,10 +223,6 @@ public final class JsAstUtils {
|
||||
arguments.addAll(newArgs);
|
||||
}
|
||||
|
||||
public static void setArguments(@NotNull JsInvocation invocation, JsExpression... arguments) {
|
||||
setArguments(invocation, Arrays.asList(arguments));
|
||||
}
|
||||
|
||||
public static void setArguments(@NotNull JsNew invocation, @NotNull List<JsExpression> newArgs) {
|
||||
List<JsExpression> arguments = invocation.getArguments();
|
||||
assert arguments.isEmpty() : "Arguments already set.";
|
||||
@@ -321,4 +252,13 @@ public final class JsAstUtils {
|
||||
}
|
||||
return invoke;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsStatement> temporariesInitialization(@NotNull TemporaryVariable... temporaries) {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
for (TemporaryVariable temporary : temporaries) {
|
||||
result.add(temporary.assignmentExpression().makeStmt());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-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.utils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public enum PredefinedAnnotation {
|
||||
|
||||
|
||||
LIBRARY("js.library"),
|
||||
NATIVE("js.native");
|
||||
|
||||
PredefinedAnnotation(@NotNull String fqName) {
|
||||
this.fqName = fqName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String fqName;
|
||||
|
||||
@NotNull
|
||||
public String getFQName() {
|
||||
return fqName;
|
||||
}
|
||||
}
|
||||
@@ -160,4 +160,18 @@ public final class PsiUtils {
|
||||
assert rangeExpression != null;
|
||||
return rangeExpression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetPattern getPattern(@NotNull JetIsExpression expression) {
|
||||
JetPattern pattern = expression.getPattern();
|
||||
assert pattern != null : "Pattern should not be null";
|
||||
return pattern;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetTypeReference getTypeReference(@NotNull JetTypePattern pattern) {
|
||||
JetTypeReference typeReference = pattern.getTypeReference();
|
||||
assert typeReference != null : "Type pattern should contain a type reference";
|
||||
return typeReference;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-13
@@ -14,30 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.translate.expression.foreach;
|
||||
package org.jetbrains.k2js.translate.utils.mutator;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
|
||||
import java.util.List;
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
//TODO: consider moving some of the binary/unary operations stuff here
|
||||
public final class ForTranslatorUtils {
|
||||
public final class AssignToExpressionMutator implements Mutator {
|
||||
|
||||
private ForTranslatorUtils() {
|
||||
@NotNull
|
||||
private final JsExpression toAssign;
|
||||
|
||||
public AssignToExpressionMutator(@NotNull JsExpression toAssign) {
|
||||
this.toAssign = toAssign;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JsStatement> temporariesInitialization(@NotNull TemporaryVariable... temporaries) {
|
||||
List<JsStatement> result = Lists.newArrayList();
|
||||
for (TemporaryVariable temporary : temporaries) {
|
||||
result.add(temporary.assignmentExpression().makeStmt());
|
||||
@Override
|
||||
public JsNode mutate(@NotNull JsNode node) {
|
||||
if (!(node instanceof JsExpression)) {
|
||||
return node;
|
||||
}
|
||||
return result;
|
||||
return assignment(toAssign, (JsExpression) node);
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-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.utils.mutator;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public final class LastExpressionMutator {
|
||||
|
||||
public static JsNode mutateLastExpression(@NotNull JsNode node, @NotNull Mutator mutator) {
|
||||
return (new LastExpressionMutator(mutator)).apply(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private final Mutator mutator;
|
||||
|
||||
private LastExpressionMutator(@NotNull Mutator mutator) {
|
||||
this.mutator = mutator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode apply(@NotNull JsNode node) {
|
||||
if (node instanceof JsBlock) {
|
||||
return applyToBlock((JsBlock) node);
|
||||
}
|
||||
if (node instanceof JsIf) {
|
||||
return applyToIf((JsIf) node);
|
||||
}
|
||||
if (node instanceof JsExprStmt) {
|
||||
return applyToStatement((JsExprStmt) node);
|
||||
}
|
||||
return mutator.mutate(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode applyToStatement(@NotNull JsExprStmt node) {
|
||||
return convertToStatement(apply(node.getExpression()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode applyToIf(@NotNull JsIf node) {
|
||||
node.setThenStmt(convertToStatement(apply(node.getThenStmt())));
|
||||
JsStatement elseStmt = node.getElseStmt();
|
||||
if (elseStmt != null) {
|
||||
node.setElseStmt(convertToStatement(apply(elseStmt)));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsNode applyToBlock(@NotNull JsBlock node) {
|
||||
List<JsStatement> statements = node.getStatements();
|
||||
|
||||
if (statements.isEmpty()) return node;
|
||||
|
||||
int size = statements.size();
|
||||
statements.set(size - 1, convertToStatement(apply(statements.get(size - 1))));
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2000-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.utils.mutator;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
public interface Mutator {
|
||||
@NotNull
|
||||
JsNode mutate(@NotNull JsNode node);
|
||||
}
|
||||
Reference in New Issue
Block a user