Merge branch 'master' of github.com:JetBrains/kotlin

This commit is contained in:
James Strachan
2012-02-29 17:23:09 +00:00
20 changed files with 287 additions and 246 deletions
@@ -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();
@@ -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);
}
}
@@ -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
@@ -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;
@@ -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
@@ -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;
@@ -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;
}
}
@@ -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);
}
}
@@ -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);
}