JS: refactor Dart AST
This commit is contained in:
@@ -9,6 +9,6 @@ import java.util.List;
|
||||
/**
|
||||
* Implemented by JavaScript objects that accept arguments.
|
||||
*/
|
||||
public interface HasArguments extends JsExpression {
|
||||
public interface HasArguments {
|
||||
List<JsExpression> getArguments();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a javascript expression for array access.
|
||||
*/
|
||||
public final class JsArrayAccess extends JsExpressionImpl {
|
||||
public final class JsArrayAccess extends JsExpression {
|
||||
private JsExpression arrayExpression;
|
||||
private JsExpression indexExpression;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class JsBinaryOperation extends JsExpressionImpl {
|
||||
public final class JsBinaryOperation extends JsExpression {
|
||||
private JsExpression arg1;
|
||||
private JsExpression arg2;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ package com.google.dart.compiler.backend.js.ast;
|
||||
import com.google.dart.compiler.util.AstUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class JsConditional extends JsExpressionImpl {
|
||||
public final class JsConditional extends JsExpression {
|
||||
private JsExpression testExpression;
|
||||
private JsExpression elseExpression;
|
||||
private JsExpression thenExpression;
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsDocComment extends JsExpressionImpl {
|
||||
public class JsDocComment extends JsExpression {
|
||||
private final Map<String, Object> tags;
|
||||
|
||||
public JsDocComment(Map<String, Object> tags) {
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JsEmptyExpression extends JsExpressionImpl {
|
||||
|
||||
JsEmptyExpression() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsStatement makeStmt() {
|
||||
return JsEmpty.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JsVisitor visitor) {
|
||||
throw new IllegalArgumentException("empty expression should not be here during generating Javascript code");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void traverse(JsVisitorWithContext visitor, JsContext ctx) {
|
||||
throw new IllegalArgumentException("empty expression should not be here during generating Javascript code");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JsEmptyExpression deepCopy() {
|
||||
return new JsEmptyExpression();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,50 @@
|
||||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
package com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface JsExpression extends JsNode {
|
||||
boolean isLeaf();
|
||||
import java.util.List;
|
||||
|
||||
public abstract class JsExpression extends SourceInfoAwareJsNode {
|
||||
/**
|
||||
* Determines whether or not this expression is a leaf, such as a
|
||||
* {@link JsNameRef}, {@link JsLiteral.JsBooleanLiteral}, and so on. Leaf expressions
|
||||
* never need to be parenthesized.
|
||||
*/
|
||||
public boolean isLeaf() {
|
||||
// Conservatively say that it isn't a leaf.
|
||||
// Individual subclasses can speak for themselves if they are a leaf.
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
JsStatement makeStmt();
|
||||
public JsStatement makeStmt() {
|
||||
return new JsExpressionStatement(this);
|
||||
}
|
||||
|
||||
protected abstract static class JsExpressionHasArguments extends JsExpression implements HasArguments {
|
||||
protected final List<JsExpression> arguments;
|
||||
|
||||
public JsExpressionHasArguments(List<JsExpression> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsExpression> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
JsExpression source(Object info);
|
||||
public JsExpression source(Object info) {
|
||||
setSource(info);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
JsExpression deepCopy();
|
||||
public abstract JsExpression deepCopy();
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
package com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
abstract class JsExpressionImpl extends SourceInfoAwareJsNode implements JsExpression {
|
||||
/**
|
||||
* Determines whether or not this expression is a leaf, such as a
|
||||
* {@link JsNameRef}, {@link JsLiteral.JsBooleanLiteral}, and so on. Leaf expressions
|
||||
* never need to be parenthesized.
|
||||
*/
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
// Conservatively say that it isn't a leaf.
|
||||
// Individual subclasses can speak for themselves if they are a leaf.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JsStatement makeStmt() {
|
||||
return new JsExpressionStatement(this);
|
||||
}
|
||||
|
||||
protected abstract static class JsExpressionHasArguments extends JsExpressionImpl implements HasArguments {
|
||||
protected final List<JsExpression> arguments;
|
||||
|
||||
public JsExpressionHasArguments(List<JsExpression> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JsExpression> getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsExpression source(Object info) {
|
||||
setSource(info);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class JsInvocation extends JsExpressionImpl.JsExpressionHasArguments {
|
||||
public final class JsInvocation extends JsExpression.JsExpressionHasArguments {
|
||||
@NotNull
|
||||
private JsExpression qualifier;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ package com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class JsLiteral extends JsExpressionImpl {
|
||||
public abstract class JsLiteral extends JsExpression {
|
||||
public static final JsValueLiteral THIS = new JsThisRef();
|
||||
public static final JsNameRef UNDEFINED = new JsNameRef("undefined");
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a JavaScript expression that references a name.
|
||||
*/
|
||||
public final class JsNameRef extends JsExpressionImpl implements HasName {
|
||||
public final class JsNameRef extends JsExpression implements HasName {
|
||||
private String ident;
|
||||
private JsName name;
|
||||
private JsExpression qualifier;
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class JsNew extends JsExpressionImpl.JsExpressionHasArguments {
|
||||
public final class JsNew extends JsExpression.JsExpressionHasArguments {
|
||||
private JsExpression constructorExpression;
|
||||
|
||||
public JsNew(JsExpression constructorExpression) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package com.google.dart.compiler.backend.js.ast;
|
||||
|
||||
public abstract class JsUnaryOperation extends JsExpressionImpl {
|
||||
public abstract class JsUnaryOperation extends JsExpression {
|
||||
|
||||
private JsExpression arg;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.metadata.*
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.js.inline.util.IdentitySet
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.inline.util.canHaveOwnSideEffect
|
||||
import org.jetbrains.kotlin.js.inline.util.rewriters.ContinueReplacingVisitor
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.*
|
||||
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.*
|
||||
@@ -296,14 +295,14 @@ internal class ExpressionDecomposer private constructor(
|
||||
// Qualifier might be a reference to lambda property. See KT-7674
|
||||
// An exception here is `fn.call()`, which are marked as side effect free. Further recognition of such
|
||||
// case in inliner might be quite difficult, so never extract such call (and other calls marked this way).
|
||||
if ((qualifier as? HasMetadata)?.sideEffects == SideEffectKind.PURE &&
|
||||
callee != null && receiver != null && receiver in containsNodeWithSideEffect
|
||||
if (qualifier.sideEffects == SideEffectKind.PURE && callee != null && receiver != null &&
|
||||
receiver in containsNodeWithSideEffect
|
||||
) {
|
||||
val receiverTmp = receiver.extractToTemporary()
|
||||
callee.qualifier = receiverTmp
|
||||
}
|
||||
else {
|
||||
if (receiver != null && callee != null && applyBindIfNecessary) {
|
||||
if (receiver != null && applyBindIfNecessary) {
|
||||
val receiverTmp = receiver.extractToTemporary()
|
||||
qualifier = JsAstUtils.invokeBind(receiverTmp, pureFqn(callee.ident, receiverTmp))
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.js.inline.util
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.js.translate.utils.jsAstUtils.any
|
||||
@@ -30,6 +29,5 @@ fun JsExpression.canHaveOwnSideEffect(vars: Set<JsName>) = when (this) {
|
||||
is JsLiteral -> false
|
||||
is JsBinaryOperation -> operator.isAssignment
|
||||
is JsNameRef -> name !in vars && sideEffects != SideEffectKind.PURE
|
||||
is HasMetadata -> sideEffects != SideEffectKind.PURE
|
||||
else -> true
|
||||
else -> sideEffects != SideEffectKind.PURE
|
||||
}
|
||||
|
||||
+5
-3
@@ -18,10 +18,12 @@ package org.jetbrains.kotlin.js.translate.callTranslator
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||
import com.google.dart.compiler.backend.js.ast.JsName
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
|
||||
@@ -84,7 +86,7 @@ fun VariableAccessInfo.constructAccessExpression(ref: JsExpression): JsExpressio
|
||||
// This is useful when passing AST to TemporaryAssignmentElimination. It can bring
|
||||
// property assignment like `obj.propertyName = $tmp` to places where `$tmp` gets its value,
|
||||
// but only when it's sure that no side effects possible.
|
||||
(ref as? HasMetadata)?.let { it.sideEffects = SideEffectKind.PURE }
|
||||
ref.sideEffects = SideEffectKind.PURE
|
||||
JsAstUtils.assignment(ref, value!!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.translate.context;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
@@ -619,13 +618,11 @@ public final class StaticContext {
|
||||
}
|
||||
|
||||
private static JsExpression applySideEffects(JsExpression expression, DeclarationDescriptor descriptor) {
|
||||
if (expression instanceof HasMetadata) {
|
||||
if (descriptor instanceof FunctionDescriptor ||
|
||||
descriptor instanceof PackageFragmentDescriptor ||
|
||||
descriptor instanceof ClassDescriptor
|
||||
) {
|
||||
MetadataProperties.setSideEffects((HasMetadata) expression, SideEffectKind.PURE);
|
||||
}
|
||||
if (descriptor instanceof FunctionDescriptor ||
|
||||
descriptor instanceof PackageFragmentDescriptor ||
|
||||
descriptor instanceof ClassDescriptor
|
||||
) {
|
||||
MetadataProperties.setSideEffects(expression, SideEffectKind.PURE);
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
-1
@@ -20,7 +20,6 @@ import com.google.dart.compiler.backend.js.ast.JsExpression;
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation;
|
||||
import com.google.dart.compiler.backend.js.ast.JsName;
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -28,13 +28,12 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class JsAstUtils {
|
||||
private static final JsNameRef DEFINE_PROPERTY = pureFqn("defineProperty", null);
|
||||
public static final JsNameRef CREATE_OBJECT = pureFqn("create", null);
|
||||
private static final JsNameRef CREATE_OBJECT = pureFqn("create", null);
|
||||
|
||||
private static final JsNameRef VALUE = new JsNameRef("value");
|
||||
private static final JsPropertyInitializer WRITABLE = new JsPropertyInitializer(pureFqn("writable", null), JsLiteral.TRUE);
|
||||
@@ -205,11 +204,6 @@ public final class JsAstUtils {
|
||||
return invokeMethod(Namer.kotlinLong(), Namer.LONG_FROM_NUMBER, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression equalsForObject(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return invokeMethod(left, Namer.EQUALS_METHOD_NAME, right);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression compareForObject(@NotNull JsExpression left, @NotNull JsExpression right) {
|
||||
return invokeMethod(left, Namer.COMPARE_TO_METHOD_NAME, right);
|
||||
@@ -267,7 +261,7 @@ public final class JsAstUtils {
|
||||
return new JsBinaryOperation(JsBinaryOperator.OR, op1, op2);
|
||||
}
|
||||
|
||||
public static void setQualifier(@NotNull JsExpression selector, @Nullable JsExpression receiver) {
|
||||
private 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);
|
||||
@@ -398,16 +392,6 @@ public final class JsAstUtils {
|
||||
return new JsVars(new JsVars.JsVar(name, expr));
|
||||
}
|
||||
|
||||
public static void setArguments(@NotNull HasArguments invocation, @NotNull List<JsExpression> newArgs) {
|
||||
List<JsExpression> arguments = invocation.getArguments();
|
||||
assert arguments.isEmpty() : "Arguments already set.";
|
||||
arguments.addAll(newArgs);
|
||||
}
|
||||
|
||||
public static void setArguments(@NotNull HasArguments invocation, JsExpression... arguments) {
|
||||
setArguments(invocation, Arrays.asList(arguments));
|
||||
}
|
||||
|
||||
public static void setParameters(@NotNull JsFunction function, @NotNull List<JsParameter> newParams) {
|
||||
List<JsParameter> parameters = function.getParameters();
|
||||
assert parameters.isEmpty() : "Arguments already set.";
|
||||
|
||||
Reference in New Issue
Block a user