K2JS: introduce "no-stdlb" parameter and use stdlib from compiler by default.
This commit is contained in:
@@ -18,12 +18,8 @@ package org.jetbrains.jet.buildtools.ant
|
|||||||
|
|
||||||
import org.apache.tools.ant.types.Path
|
import org.apache.tools.ant.types.Path
|
||||||
import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments
|
import org.jetbrains.jet.cli.common.arguments.K2JSCompilerArguments
|
||||||
import org.jetbrains.jet.cli.common.messages.MessageCollectorPlainTextToStream
|
|
||||||
import org.jetbrains.jet.cli.js.K2JSCompiler
|
import org.jetbrains.jet.cli.js.K2JSCompiler
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.apache.tools.ant.BuildException
|
|
||||||
import org.jetbrains.jet.cli.common.ExitCode
|
|
||||||
import org.jetbrains.jet.config.Services
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kotlin JavaScript compiler Ant task.
|
* Kotlin JavaScript compiler Ant task.
|
||||||
@@ -58,6 +54,13 @@ public class Kotlin2JsTask : KotlinCompilerBaseTask<K2JSCompilerArguments>() {
|
|||||||
override fun fillSpecificArguments() {
|
override fun fillSpecificArguments() {
|
||||||
arguments.outputFile = getPath(output!!)
|
arguments.outputFile = getPath(output!!)
|
||||||
|
|
||||||
|
arguments.noStdlib = noStdlib
|
||||||
|
|
||||||
|
// TODO: write test
|
||||||
|
library?.let {
|
||||||
|
arguments.libraryFiles = it.list().map { getPath(File(it)) }.copyToArray()
|
||||||
|
}
|
||||||
|
|
||||||
arguments.outputPrefix = outputPrefix?.canonicalPath
|
arguments.outputPrefix = outputPrefix?.canonicalPath
|
||||||
arguments.outputPostfix = outputPostfix?.canonicalPath
|
arguments.outputPostfix = outputPostfix?.canonicalPath
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ public class Kotlin2JvmTask : KotlinCompilerBaseTask<K2JVMCompilerArguments>()
|
|||||||
override val arguments = K2JVMCompilerArguments()
|
override val arguments = K2JVMCompilerArguments()
|
||||||
override val compiler = K2JVMCompiler()
|
override val compiler = K2JVMCompiler()
|
||||||
|
|
||||||
public var noStdlib: Boolean = false
|
|
||||||
public var externalAnnotations: Path? = null
|
public var externalAnnotations: Path? = null
|
||||||
public var includeRuntime: Boolean = true
|
public var includeRuntime: Boolean = true
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public abstract class KotlinCompilerBaseTask<T : CommonCompilerArguments> : Task
|
|||||||
public var verbose: Boolean = false
|
public var verbose: Boolean = false
|
||||||
public var printVersion: Boolean = false
|
public var printVersion: Boolean = false
|
||||||
|
|
||||||
|
public var noStdlib: Boolean = false
|
||||||
|
|
||||||
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
|
public val additionalArguments: MutableList<Commandline.Argument> = arrayListOf()
|
||||||
|
|
||||||
public fun createSrc(): Path {
|
public fun createSrc(): Path {
|
||||||
|
|||||||
@@ -221,7 +221,7 @@
|
|||||||
<property name="compiled.stdlib.js" value="stdlib.js" />
|
<property name="compiled.stdlib.js" value="stdlib.js" />
|
||||||
<property name="stdlib.js.dir" value="${basedir}/js/js.translator/testData" />
|
<property name="stdlib.js.dir" value="${basedir}/js/js.translator/testData" />
|
||||||
|
|
||||||
<kotlin2js output="${output}/${compiled.stdlib.js}" main="noCall">
|
<kotlin2js output="${output}/${compiled.stdlib.js}" noStdlib="true" main="noCall">
|
||||||
<src>
|
<src>
|
||||||
<fileset refid="kotlin.builtin.files" />
|
<fileset refid="kotlin.builtin.files" />
|
||||||
<resources refid="js.lib.files" />
|
<resources refid="js.lib.files" />
|
||||||
|
|||||||
+3
@@ -28,6 +28,9 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
|
|||||||
@ValueDescription("<path>")
|
@ValueDescription("<path>")
|
||||||
public String outputFile;
|
public String outputFile;
|
||||||
|
|
||||||
|
@Argument(value = "no-stdlib", description = "Don't use bundled Kotlin stdlib")
|
||||||
|
public boolean noStdlib;
|
||||||
|
|
||||||
@Argument(value = "library-files", description = "Path to zipped library sources or kotlin files separated by commas")
|
@Argument(value = "library-files", description = "Path to zipped library sources or kotlin files separated by commas")
|
||||||
@ValueDescription("<path[,]>")
|
@ValueDescription("<path[,]>")
|
||||||
public String[] libraryFiles;
|
public String[] libraryFiles;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
|||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.util.Consumer;
|
import com.intellij.util.Consumer;
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
|
import com.intellij.util.SmartList;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import kotlin.Function0;
|
import kotlin.Function0;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -51,12 +52,12 @@ import org.jetbrains.jet.lang.psi.JetFile;
|
|||||||
import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression;
|
import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression;
|
||||||
import org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative;
|
import org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative;
|
||||||
import org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules;
|
import org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules;
|
||||||
|
import org.jetbrains.jet.utils.PathUtil;
|
||||||
import org.jetbrains.k2js.analyze.TopDownAnalyzerFacadeForJS;
|
import org.jetbrains.k2js.analyze.TopDownAnalyzerFacadeForJS;
|
||||||
import org.jetbrains.k2js.config.*;
|
import org.jetbrains.k2js.config.*;
|
||||||
import org.jetbrains.k2js.facade.MainCallParameters;
|
import org.jetbrains.k2js.facade.MainCallParameters;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.cli.common.ExitCode.COMPILATION_ERROR;
|
import static org.jetbrains.jet.cli.common.ExitCode.COMPILATION_ERROR;
|
||||||
@@ -211,8 +212,17 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
|||||||
String moduleId = FileUtil.getNameWithoutExtension(new File(arguments.outputFile));
|
String moduleId = FileUtil.getNameWithoutExtension(new File(arguments.outputFile));
|
||||||
boolean inlineEnabled = !arguments.noInline;
|
boolean inlineEnabled = !arguments.noInline;
|
||||||
|
|
||||||
|
List<String> libraryFiles = new SmartList<String>();
|
||||||
|
if (!arguments.noStdlib) {
|
||||||
|
libraryFiles.add(0, PathUtil.getKotlinPathsForCompiler().getJsLibJarPath().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
if (arguments.libraryFiles != null) {
|
if (arguments.libraryFiles != null) {
|
||||||
return new LibrarySourcesConfig(project, moduleId, Arrays.asList(arguments.libraryFiles), ecmaVersion, arguments.sourceMap, inlineEnabled);
|
ContainerUtil.addAllNotNull(libraryFiles, arguments.libraryFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!libraryFiles.isEmpty()) {
|
||||||
|
return new LibrarySourcesConfig(project, moduleId, libraryFiles, ecmaVersion, arguments.sourceMap, inlineEnabled);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// lets discover the JS library definitions on the classpath
|
// lets discover the JS library definitions on the classpath
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ public class AntTaskJsTest extends AntTaskBaseTest {
|
|||||||
doJsAntTest();
|
doJsAntTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleWithStdlib() throws Exception {
|
||||||
|
doJsAntTest();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void simpleWithMainFQArgs() throws Exception {
|
public void simpleWithMainFQArgs() throws Exception {
|
||||||
doJsAntTest();
|
doJsAntTest();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/hello.kt" output="${temp}/out.js">
|
<kotlin2js src="${test.data}/hello.kt" noStdlib="true" output="${temp}/out.js">
|
||||||
<compilerarg value="-Xno-inline"/>
|
<compilerarg value="-Xno-inline"/>
|
||||||
</kotlin2js>
|
</kotlin2js>
|
||||||
</target>
|
</target>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" outputPrefix="${test.data}/prefix" outputPostfix="${test.data}/postfix" />
|
<kotlin2js src="${test.data}/root1"
|
||||||
|
noStdlib="true"
|
||||||
|
output="${temp}/out.js"
|
||||||
|
outputPrefix="${test.data}/prefix"
|
||||||
|
outputPostfix="${test.data}/postfix" />
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" >
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" >
|
||||||
<src>
|
<src>
|
||||||
<pathelement path="${test.data}/bar.kt"/>
|
<pathelement path="${test.data}/bar.kt"/>
|
||||||
<fileset dir="${test.data}/root2">
|
<fileset dir="${test.data}/root2">
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" outputPostfix="${test.data}/postfix" />
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" outputPostfix="${test.data}/postfix" />
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" outputPrefix="${test.data}/prefix" />
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" outputPrefix="${test.data}/prefix" />
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js"/>
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" main="call"/>
|
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" noStdlib="true" main="call"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" main="call"/>
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" main="call"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
OUT:
|
||||||
|
Buildfile: [TestData]/build.xml
|
||||||
|
|
||||||
|
build:
|
||||||
|
[kotlin2js] Compiling [[TestData]/root1] => [[Temp]/out.js]
|
||||||
|
|
||||||
|
BUILD SUCCESSFUL
|
||||||
|
Total time: [time]
|
||||||
|
|
||||||
|
Return code: 0
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<project name="Ant Task Test" default="build">
|
||||||
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
|
<target name="build">
|
||||||
|
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" main="call"/>
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
var ok = "FAIL"
|
||||||
|
|
||||||
|
val hello = Pair("Hello", "World")
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
ok = "OK"
|
||||||
|
println(hello.first + " " + hello.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String = ok
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" main="call"/>
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" main="call"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" sourcemap="true"/>
|
<kotlin2js src="${test.data}/root1" noStdlib="true" output="${temp}/out.js" sourcemap="true"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" verbose="true"/>
|
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" noStdlib="true" verbose="true"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
<taskdef resource="org/jetbrains/jet/buildtools/ant/antlib.xml" classpath="${kotlin.lib}/kotlin-ant.jar"/>
|
||||||
|
|
||||||
<target name="build">
|
<target name="build">
|
||||||
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" printVersion="true"/>
|
<kotlin2js src="${test.data}/root1" output="${temp}/out.js" noStdlib="true" printVersion="true"/>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
Usage: kotlinc-js <options> <source files>
|
Usage: kotlinc-js <options> <source files>
|
||||||
where possible options include:
|
where possible options include:
|
||||||
-output <path> Output file path
|
-output <path> Output file path
|
||||||
|
-no-stdlib Don't use bundled Kotlin stdlib
|
||||||
-library-files <path[,]> Path to zipped library sources or kotlin files separated by commas
|
-library-files <path[,]> Path to zipped library sources or kotlin files separated by commas
|
||||||
-source-map Generate source map
|
-source-map Generate source map
|
||||||
-target <version> Generate JS files for specific ECMA version (only ECMA 5 is supported)
|
-target <version> Generate JS files for specific ECMA version (only ECMA 5 is supported)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
$TESTDATA_DIR$/simple2js.kt
|
$TESTDATA_DIR$/simple2js.kt
|
||||||
|
-no-stdlib
|
||||||
-output
|
-output
|
||||||
$TEMP_DIR$/out.js
|
$TEMP_DIR$/out.js
|
||||||
-output-postfix
|
-output-postfix
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
$TESTDATA_DIR$/simple2js.kt
|
$TESTDATA_DIR$/simple2js.kt
|
||||||
|
-no-stdlib
|
||||||
-output
|
-output
|
||||||
$TEMP_DIR$/out.js
|
$TEMP_DIR$/out.js
|
||||||
-output-prefix
|
-output-prefix
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
$TESTDATA_DIR$/simple2js.kt
|
$TESTDATA_DIR$/simple2js.kt
|
||||||
|
-no-stdlib
|
||||||
-output
|
-output
|
||||||
$TEMP_DIR$/out.js
|
$TEMP_DIR$/out.js
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
$TESTDATA_DIR$/../warnings.kt
|
$TESTDATA_DIR$/../warnings.kt
|
||||||
|
-no-stdlib
|
||||||
-nowarn
|
-nowarn
|
||||||
-output
|
-output
|
||||||
$TEMP_DIR$/out.js
|
$TEMP_DIR$/out.js
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ public class KotlinCompilerRunner {
|
|||||||
List<String> libraryFiles,
|
List<String> libraryFiles,
|
||||||
K2JSCompilerArguments settings
|
K2JSCompilerArguments settings
|
||||||
) {
|
) {
|
||||||
|
settings.noStdlib = true;
|
||||||
settings.freeArgs = ContainerUtil.map(sourceFiles, new Function<File, String>() {
|
settings.freeArgs = ContainerUtil.map(sourceFiles, new Function<File, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String fun(File file) {
|
public String fun(File file) {
|
||||||
|
|||||||
+1
@@ -155,6 +155,7 @@ public class K2JSCompilerMojo extends KotlinCompileMojoBase<K2JSCompilerArgument
|
|||||||
@Override
|
@Override
|
||||||
protected void configureSpecificCompilerArguments(@NotNull K2JSCompilerArguments arguments) throws MojoExecutionException {
|
protected void configureSpecificCompilerArguments(@NotNull K2JSCompilerArguments arguments) throws MojoExecutionException {
|
||||||
arguments.outputFile = outputFile;
|
arguments.outputFile = outputFile;
|
||||||
|
arguments.noStdlib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user