clean up foreach package
This commit is contained in:
+25
-30
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.expression.foreach;
|
package org.jetbrains.k2js.translate.expression.foreach;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -32,6 +31,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
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.DescriptorUtils.getClassDescriptorForType;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||||
@@ -58,64 +58,59 @@ public final class ArrayForTranslator extends ForTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TemporaryVariable rangeExpression;
|
private final TemporaryVariable loopRange;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable end;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable index;
|
||||||
|
|
||||||
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
private ArrayForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
super(forExpression, context);
|
super(forExpression, context);
|
||||||
rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
loopRange = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
||||||
|
JsExpression length = LengthIntrinsic.INSTANCE.apply(loopRange.reference(), Collections.<JsExpression>emptyList(), context());
|
||||||
|
end = context().declareTemporary(length);
|
||||||
|
index = context().declareTemporary(program().getNumberLiteral(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsBlock translate() {
|
private JsBlock translate() {
|
||||||
JsExpression length = LengthIntrinsic.INSTANCE.apply(rangeExpression.reference(), Collections.<JsExpression>emptyList(), context());
|
List<JsStatement> blockStatements = temporariesInitialization(loopRange, end);
|
||||||
TemporaryVariable end = context().declareTemporary(length);
|
blockStatements.add(generateForExpression());
|
||||||
List<JsStatement> blockStatements = temporariesInitialization(rangeExpression, end);
|
|
||||||
blockStatements.add(generateForExpression(end));
|
|
||||||
return AstUtil.newBlock(blockStatements);
|
return AstUtil.newBlock(blockStatements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsFor generateForExpression(@NotNull TemporaryVariable end) {
|
private JsFor generateForExpression() {
|
||||||
JsFor result = new JsFor();
|
JsFor result = new JsFor();
|
||||||
//TODO: make index instance variable
|
result.setInitVars(initExpression());
|
||||||
TemporaryVariable indexVar = context().declareTemporary(program().getNumberLiteral(0));
|
result.setCondition(getCondition());
|
||||||
result.setInitVars(initExpression(indexVar));
|
result.setIncrExpr(getIncrExpression());
|
||||||
result.setCondition(getCondition(end, indexVar));
|
result.setBody(getBody());
|
||||||
result.setIncrExpr(getIncrExpression(indexVar));
|
|
||||||
result.setBody(getBody(indexVar));
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsStatement getBody(@NotNull TemporaryVariable index) {
|
private JsStatement getBody() {
|
||||||
JsArrayAccess arrayAccess = new JsArrayAccess(rangeExpression.reference(), index.reference());
|
JsArrayAccess arrayAccess = new JsArrayAccess(loopRange.reference(), index.reference());
|
||||||
JsStatement currentVar = AstUtil.newVar(parameterName, arrayAccess);
|
JsStatement currentVar = AstUtil.newVar(parameterName, arrayAccess);
|
||||||
JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
|
JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
|
||||||
return AstUtil.newBlock(currentVar, realBody);
|
return AstUtil.newBlock(currentVar, realBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsVars initExpression(TemporaryVariable start) {
|
private JsVars initExpression() {
|
||||||
return AstUtil.newVar(start.name(), program().getNumberLiteral(0));
|
return AstUtil.newVar(index.name(), program().getNumberLiteral(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getCondition(TemporaryVariable end, TemporaryVariable index) {
|
private JsExpression getCondition() {
|
||||||
return AstUtil.notEqual(index.reference(), end.reference());
|
return AstUtil.notEqual(index.reference(), end.reference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getIncrExpression(@NotNull TemporaryVariable index) {
|
private JsExpression getIncrExpression() {
|
||||||
return new JsPrefixOperation(JsUnaryOperator.INC, index.reference());
|
return new JsPrefixOperation(JsUnaryOperator.INC, index.reference());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: move somewhere util
|
|
||||||
@NotNull
|
|
||||||
private List<JsStatement> temporariesInitialization(TemporaryVariable... temporaries) {
|
|
||||||
List<JsStatement> result = Lists.newArrayList();
|
|
||||||
for (TemporaryVariable temporary : temporaries) {
|
|
||||||
result.add(temporary.assignmentExpression().makeStmt());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ public abstract class ForTranslator extends AbstractTranslator {
|
|||||||
if (RangeLiteralForTranslator.isApplicable(expression, context)) {
|
if (RangeLiteralForTranslator.isApplicable(expression, context)) {
|
||||||
return RangeLiteralForTranslator.translate(expression, context);
|
return RangeLiteralForTranslator.translate(expression, context);
|
||||||
}
|
}
|
||||||
if (ArrayForTranslator.isApplicable(expression, context)) {
|
|
||||||
return ArrayForTranslator.translate(expression, context);
|
|
||||||
}
|
|
||||||
if (RangeForTranslator.isApplicable(expression, context)) {
|
if (RangeForTranslator.isApplicable(expression, context)) {
|
||||||
return RangeForTranslator.translate(expression, context);
|
return RangeForTranslator.translate(expression, context);
|
||||||
}
|
}
|
||||||
|
if (ArrayForTranslator.isApplicable(expression, context)) {
|
||||||
|
return ArrayForTranslator.translate(expression, context);
|
||||||
|
}
|
||||||
return IteratorForTranslator.translate(expression, context);
|
return IteratorForTranslator.translate(expression, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.expression.foreach;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.dart.compiler.backend.js.ast.JsStatement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Pavel Talanov
|
||||||
|
*/
|
||||||
|
public final class ForTranslatorUtils {
|
||||||
|
|
||||||
|
private ForTranslatorUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-8
@@ -44,23 +44,25 @@ public final class IteratorForTranslator extends ForTranslator {
|
|||||||
return (new IteratorForTranslator(expression, context).translate());
|
return (new IteratorForTranslator(expression, context).translate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable iterator;
|
||||||
|
|
||||||
private IteratorForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
private IteratorForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
super(forExpression, context);
|
super(forExpression, context);
|
||||||
|
iterator = context().declareTemporary(iteratorMethodInvocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsBlock translate() {
|
private JsBlock translate() {
|
||||||
TemporaryVariable iterator = context().declareTemporary(iteratorMethodInvocation());
|
JsBlock bodyBlock = generateCycleBody();
|
||||||
JsBlock bodyBlock = generateCycleBody(parameterName, iterator);
|
JsWhile cycle = new JsWhile(hasNextMethodInvocation(), bodyBlock);
|
||||||
JsWhile cycle = new JsWhile(hasNextMethodInvocation(iterator), bodyBlock);
|
|
||||||
return AstUtil.newBlock(iterator.assignmentExpression().makeStmt(), cycle);
|
return AstUtil.newBlock(iterator.assignmentExpression().makeStmt(), cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsBlock generateCycleBody(@NotNull JsName parameterName, @NotNull TemporaryVariable iterator) {
|
private JsBlock generateCycleBody() {
|
||||||
JsBlock cycleBody = new JsBlock();
|
JsBlock cycleBody = new JsBlock();
|
||||||
JsStatement parameterAssignment =
|
JsStatement parameterAssignment = AstUtil.newVar(parameterName, nextMethodInvocation());
|
||||||
AstUtil.newVar(parameterName, nextMethodInvocation(iterator));
|
|
||||||
JsNode originalBody = Translation.translateExpression(getLoopBody(expression), context().innerBlock(cycleBody));
|
JsNode originalBody = Translation.translateExpression(getLoopBody(expression), context().innerBlock(cycleBody));
|
||||||
cycleBody.addStatement(parameterAssignment);
|
cycleBody.addStatement(parameterAssignment);
|
||||||
cycleBody.addStatement(AstUtil.convertToBlock(originalBody));
|
cycleBody.addStatement(AstUtil.convertToBlock(originalBody));
|
||||||
@@ -68,13 +70,13 @@ public final class IteratorForTranslator extends ForTranslator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression nextMethodInvocation(@NotNull TemporaryVariable iterator) {
|
private JsExpression nextMethodInvocation() {
|
||||||
FunctionDescriptor nextFunction = getNextFunction(context().bindingContext(), getLoopRange(expression));
|
FunctionDescriptor nextFunction = getNextFunction(context().bindingContext(), getLoopRange(expression));
|
||||||
return translateMethodInvocation(iterator.reference(), nextFunction);
|
return translateMethodInvocation(iterator.reference(), nextFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression hasNextMethodInvocation(@NotNull TemporaryVariable iterator) {
|
private JsExpression hasNextMethodInvocation() {
|
||||||
CallableDescriptor hasNextFunction = getHasNextCallable(context().bindingContext(), getLoopRange(expression));
|
CallableDescriptor hasNextFunction = getHasNextCallable(context().bindingContext(), getLoopRange(expression));
|
||||||
return translateMethodInvocation(iterator.reference(), hasNextFunction);
|
return translateMethodInvocation(iterator.reference(), hasNextFunction);
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-28
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.expression.foreach;
|
package org.jetbrains.k2js.translate.expression.foreach;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*;
|
import com.google.dart.compiler.backend.js.ast.*;
|
||||||
import com.google.dart.compiler.util.AstUtil;
|
import com.google.dart.compiler.util.AstUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -30,6 +29,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
|
|||||||
|
|
||||||
import java.util.List;
|
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.DescriptorUtils.getClassDescriptorForType;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||||
@@ -55,51 +55,54 @@ public final class RangeForTranslator extends ForTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TemporaryVariable rangeExpression;
|
private final TemporaryVariable rangeExpression;
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable incrVar;
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable start;
|
||||||
|
@NotNull
|
||||||
|
private final TemporaryVariable end;
|
||||||
|
|
||||||
private RangeForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
private RangeForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
|
||||||
super(forExpression, context);
|
super(forExpression, context);
|
||||||
rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
rangeExpression = context.declareTemporary(Translation.translateAsExpression(getLoopRange(expression), context));
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private JsBlock translate() {
|
|
||||||
//TODO: make fields
|
|
||||||
JsExpression isReversed = callFunction("get_reversed");
|
JsExpression isReversed = callFunction("get_reversed");
|
||||||
JsConditional incrVarValue = new JsConditional(isReversed,
|
JsConditional incrVarValue = new JsConditional(isReversed,
|
||||||
program().getNumberLiteral(-1),
|
program().getNumberLiteral(-1),
|
||||||
program().getNumberLiteral(1));
|
program().getNumberLiteral(1));
|
||||||
TemporaryVariable incrVar = context().declareTemporary(incrVarValue);
|
incrVar = context().declareTemporary(incrVarValue);
|
||||||
TemporaryVariable start = context().declareTemporary(callFunction("get_start"));
|
start = context().declareTemporary(callFunction("get_start"));
|
||||||
TemporaryVariable end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference()));
|
end = context().declareTemporary(new JsBinaryOperation(JsBinaryOperator.ADD, callFunction("get_end"), incrVar.reference()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private JsBlock translate() {
|
||||||
List<JsStatement> blockStatements = temporariesInitialization(rangeExpression, incrVar, start, end);
|
List<JsStatement> blockStatements = temporariesInitialization(rangeExpression, incrVar, start, end);
|
||||||
blockStatements.add(generateForExpression(incrVar, start, end));
|
blockStatements.add(generateForExpression());
|
||||||
return AstUtil.newBlock(blockStatements);
|
return AstUtil.newBlock(blockStatements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsFor generateForExpression(@NotNull TemporaryVariable incrVar,
|
private JsFor generateForExpression() {
|
||||||
@NotNull TemporaryVariable start,
|
|
||||||
@NotNull TemporaryVariable end) {
|
|
||||||
JsFor result = new JsFor();
|
JsFor result = new JsFor();
|
||||||
result.setInitVars(initExpression(start, parameterName));
|
result.setInitVars(initExpression());
|
||||||
result.setCondition(getCondition(end, parameterName));
|
result.setCondition(getCondition());
|
||||||
result.setIncrExpr(getIncrExpression(incrVar, parameterName));
|
result.setIncrExpr(getIncrExpression());
|
||||||
result.setBody(Translation.translateAsStatement(getLoopBody(expression), context()));
|
result.setBody(Translation.translateAsStatement(getLoopBody(expression), context()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsVars initExpression(TemporaryVariable start, JsName parameterName) {
|
private JsVars initExpression() {
|
||||||
return AstUtil.newVar(parameterName, start.reference());
|
return AstUtil.newVar(parameterName, start.reference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getCondition(TemporaryVariable end, JsName parameterName) {
|
private JsExpression getCondition() {
|
||||||
return AstUtil.notEqual(parameterName.makeRef(), end.reference());
|
return AstUtil.notEqual(parameterName.makeRef(), end.reference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JsExpression getIncrExpression(@NotNull TemporaryVariable incrVar, @NotNull JsName parameterName) {
|
private JsExpression getIncrExpression() {
|
||||||
return new JsBinaryOperation(JsBinaryOperator.ASG_ADD, parameterName.makeRef(), incrVar.reference());
|
return new JsBinaryOperation(JsBinaryOperator.ASG_ADD, parameterName.makeRef(), incrVar.reference());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,13 +117,4 @@ public final class RangeForTranslator extends ForTranslator {
|
|||||||
private JsExpression callFunction(@NotNull String funName) {
|
private JsExpression callFunction(@NotNull String funName) {
|
||||||
return AstUtil.newInvocation(getField(funName));
|
return AstUtil.newInvocation(getField(funName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private List<JsStatement> temporariesInitialization(TemporaryVariable... temporaries) {
|
|
||||||
List<JsStatement> result = Lists.newArrayList();
|
|
||||||
for (TemporaryVariable temporary : temporaries) {
|
|
||||||
result.add(temporary.assignmentExpression().makeStmt());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-11
@@ -29,6 +29,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.k2js.translate.expression.foreach.ForTranslatorUtils.temporariesInitialization;
|
||||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateLeftExpression;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRightExpression;
|
||||||
@@ -37,7 +38,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.translateRight
|
|||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: respect reverse semantics
|
// TODO: implement reverse semantics
|
||||||
public final class RangeLiteralForTranslator extends ForTranslator {
|
public final class RangeLiteralForTranslator extends ForTranslator {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -108,14 +109,4 @@ public final class RangeLiteralForTranslator extends ForTranslator {
|
|||||||
private JsExpression getIncrExpression() {
|
private JsExpression getIncrExpression() {
|
||||||
return new JsPrefixOperation(JsUnaryOperator.INC, parameterName.makeRef());
|
return new JsPrefixOperation(JsUnaryOperator.INC, parameterName.makeRef());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO : UTIL!!
|
|
||||||
@NotNull
|
|
||||||
private List<JsStatement> temporariesInitialization(@NotNull TemporaryVariable... temporaries) {
|
|
||||||
List<JsStatement> result = Lists.newArrayList();
|
|
||||||
for (TemporaryVariable temporary : temporaries) {
|
|
||||||
result.add(temporary.assignmentExpression().makeStmt());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user