diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java index f4716276339..2f8ae7df208 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTest.java @@ -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 jetFiles = Lists.newArrayList(); for (TestFile testFileFile : testFileFiles) { jetFiles.add(testFileFile.jetFile); } - BindingContext bindingContext; - if (importJdk) { - bindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(getProject(), jetFiles, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); - } - else { - bindingContext = AnalyzingUtils.analyzeFiles(getProject(), Configuration.EMPTY, jetFiles, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); - } + BindingContext bindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(getProject(), jetFiles, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY); boolean ok = true; diff --git a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java index 890f0624499..cfb625378d8 100644 --- a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java +++ b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacade.java @@ -70,8 +70,6 @@ public final class AnalyzerFacade { } } - //TODO: use some mechanism to avoid this - //TODO: move method somewhere @NotNull public static List withJsLibAdded(@NotNull List files, @NotNull Config config) { List allFiles = new ArrayList(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index bb3de688359..1d26fa1931c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -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 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 namesAnnotatedAsLibraryHasUnobfuscatableNames = new Rule() { + Rule predefinedObjectsHasUnobfuscatableNames = new Rule() { @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 namesForNativeObjectsAreUnobfuscatable = new Rule() { - @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 overridingDescriptorsReferToOriginalName = new Rule() { @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 membersOfAnnotatedClassesHaveKotlinQualifier = new Rule() { - @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); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index fa6c0c2c373..9cbeb64ef1d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -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 { 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(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java index eeca826c737..3c4b5e224c4 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/FunctionTranslator.java @@ -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); - } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java index 73401186594..77ed901a1ff 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/PatternTranslator.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java index d33d534b17e..ddb29be29e1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java index fa2d508388b..20a8158a63e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java @@ -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; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java index 831769a86d1..8cb6a0b946a 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslator.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java index c509b2fb80a..36290b119a6 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java @@ -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; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java index 2f4baa5c046..c004d065d4b 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeLiteralForTranslator.java @@ -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; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java index ecd9dd8d725..8025411bb55 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -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(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java index d169f11ac6e..76ac624b8c5 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java @@ -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); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index 0e02c4b1114..985d5b6da16 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -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); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java index f2cdff1975c..b6324ae7cb2 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsAstUtils.java @@ -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 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 newArgs) { List arguments = invocation.getArguments(); assert arguments.isEmpty() : "Arguments already set."; @@ -321,4 +252,13 @@ public final class JsAstUtils { } return invoke; } + + @NotNull + public static List temporariesInitialization(@NotNull TemporaryVariable... temporaries) { + List result = Lists.newArrayList(); + for (TemporaryVariable temporary : temporaries) { + result.add(temporary.assignmentExpression().makeStmt()); + } + return result; + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/PredefinedAnnotation.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PredefinedAnnotation.java new file mode 100644 index 00000000000..2d7c0d90a26 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PredefinedAnnotation.java @@ -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; + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java index 1625d013acb..d5af36f24f7 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/PsiUtils.java @@ -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; + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/AssignToExpressionMutator.java similarity index 50% rename from js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java rename to js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/AssignToExpressionMutator.java index 6dc81395ca3..b2aa909e59c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ForTranslatorUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/AssignToExpressionMutator.java @@ -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 temporariesInitialization(@NotNull TemporaryVariable... temporaries) { - List 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); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/LastExpressionMutator.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/LastExpressionMutator.java new file mode 100644 index 00000000000..9e6eba1c1f3 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/LastExpressionMutator.java @@ -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 statements = node.getStatements(); + + if (statements.isEmpty()) return node; + + int size = statements.size(); + statements.set(size - 1, convertToStatement(apply(statements.get(size - 1)))); + return node; + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/Mutator.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/Mutator.java new file mode 100644 index 00000000000..b43b76ae57b --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/mutator/Mutator.java @@ -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); +}