JS: underline js() errors for non-string-literal constants
This commit is contained in:
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap;
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap;
|
||||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer;
|
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticRenderer;
|
||||||
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs;
|
||||||
|
import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallDataHtmlRenderer;
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||||
@@ -125,7 +127,8 @@ public class IdeErrorMessages {
|
|||||||
|
|
||||||
MAP.put(CONFLICTING_JVM_DECLARATIONS, "<html>Platform declaration clash: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
MAP.put(CONFLICTING_JVM_DECLARATIONS, "<html>Platform declaration clash: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||||
MAP.put(ACCIDENTAL_OVERRIDE, "<html>Accidental override: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
MAP.put(ACCIDENTAL_OVERRIDE, "<html>Accidental override: {0}</html>", HTML_CONFLICTING_JVM_DECLARATIONS_DATA);
|
||||||
|
MAP.put(ErrorsJs.JSCODE_ERROR, "<html>JavaScript: {0}</html>", JsCallDataHtmlRenderer.INSTANCE$);
|
||||||
|
MAP.put(ErrorsJs.JSCODE_WARNING, "<html>JavaScript: {0}</html>", JsCallDataHtmlRenderer.INSTANCE$);
|
||||||
MAP.setImmutable();
|
MAP.setImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -31,9 +31,9 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by Delegates.lazy {
|
|||||||
put(ErrorsJs.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE, "Native getter''s return type should be nullable")
|
put(ErrorsJs.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE, "Native getter''s return type should be nullable")
|
||||||
put(ErrorsJs.NATIVE_SETTER_WRONG_RETURN_TYPE, "Native setter''s return type should be ''Unit'' or a supertype of the second parameter''s type")
|
put(ErrorsJs.NATIVE_SETTER_WRONG_RETURN_TYPE, "Native setter''s return type should be ''Unit'' or a supertype of the second parameter''s type")
|
||||||
put(ErrorsJs.NATIVE_INDEXER_WRONG_PARAMETER_COUNT, "Expected {0} parameters for native {1}", Renderers.TO_STRING, Renderers.STRING)
|
put(ErrorsJs.NATIVE_INDEXER_WRONG_PARAMETER_COUNT, "Expected {0} parameters for native {1}", Renderers.TO_STRING, Renderers.STRING)
|
||||||
put(ErrorsJs.JSCODE_ERROR, "JavaScript: {0}", Renderers.TO_STRING, Renderers.TO_STRING)
|
put(ErrorsJs.JSCODE_ERROR, "JavaScript: {0}", JsCallDataTextRenderer)
|
||||||
put(ErrorsJs.JSCODE_WARNING, "JavaScript: {0}", Renderers.TO_STRING, Renderers.TO_STRING)
|
put(ErrorsJs.JSCODE_WARNING, "JavaScript: {0}", JsCallDataTextRenderer)
|
||||||
put(ErrorsJs.JSCODE_ARGUMENT_SHOULD_BE_LITERAL, "Argument must be string literal")
|
put(ErrorsJs.JSCODE_ARGUMENT_SHOULD_BE_CONSTANT, "Argument must be string constant")
|
||||||
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.kotlin.js.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.renderer.Renderer
|
||||||
|
import org.jetbrains.kotlin.resolve.diagnostics.JsCallData
|
||||||
|
import org.jetbrains.kotlin.resolve.diagnostics.JsCallDataWithCode
|
||||||
|
import com.google.gwt.dev.js.rhino.Utils.isEndOfLine
|
||||||
|
|
||||||
|
abstract class JsCallDataRenderer : Renderer<JsCallData> {
|
||||||
|
protected abstract fun format(data: JsCallDataWithCode): String
|
||||||
|
|
||||||
|
override fun render(data: JsCallData?): String =
|
||||||
|
when (data) {
|
||||||
|
is JsCallDataWithCode -> format(data)
|
||||||
|
is JsCallData -> data.message
|
||||||
|
else -> throw AssertionError("Cannot render null data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object JsCallDataTextRenderer : JsCallDataRenderer() {
|
||||||
|
override fun format(data: JsCallDataWithCode): String {
|
||||||
|
val codeRange = data.codeRange
|
||||||
|
val code = data.code.underlineAsText(codeRange.getStartOffset(), codeRange.getEndOffset())
|
||||||
|
return "${data.message} in code:\n${code}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public object JsCallDataHtmlRenderer : JsCallDataRenderer() {
|
||||||
|
override fun format(data: JsCallDataWithCode): String {
|
||||||
|
val codeRange = data.codeRange
|
||||||
|
val code = data.code.underlineAsHtml(codeRange.getStartOffset(), codeRange.getEndOffset())
|
||||||
|
return "${data.message} in code:<br><pre>${code}</pre>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Underlines string in given rage.
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* var = 10;
|
||||||
|
* ^^^^
|
||||||
|
*/
|
||||||
|
public fun String.underlineAsText(from: Int, to: Int): String {
|
||||||
|
val lines = StringBuilder()
|
||||||
|
var marks = StringBuilder()
|
||||||
|
var lineWasMarked = false
|
||||||
|
|
||||||
|
for (i in indices) {
|
||||||
|
val c = charAt(i)
|
||||||
|
val mark: Char
|
||||||
|
|
||||||
|
mark = when (i) {
|
||||||
|
in from..to -> '^'
|
||||||
|
else -> ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.append(c)
|
||||||
|
marks.append(mark)
|
||||||
|
lineWasMarked = lineWasMarked || mark != ' '
|
||||||
|
|
||||||
|
if (isEndOfLine(c.toInt())) {
|
||||||
|
if (lineWasMarked) {
|
||||||
|
lines.appendln(marks.toString().trimTrailing())
|
||||||
|
lineWasMarked = false
|
||||||
|
}
|
||||||
|
|
||||||
|
marks = StringBuilder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineWasMarked) {
|
||||||
|
lines.appendln()
|
||||||
|
lines.append(marks.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun String.underlineAsHtml(from: Int, to: Int): String {
|
||||||
|
val lines = StringBuilder()
|
||||||
|
var openMarker = false
|
||||||
|
val underlineStart = "<u>"
|
||||||
|
val underlineEnd = "</u>"
|
||||||
|
|
||||||
|
for (i in indices) {
|
||||||
|
val c = charAt(i)
|
||||||
|
|
||||||
|
val mark = when (i) {
|
||||||
|
from -> {
|
||||||
|
openMarker = true
|
||||||
|
underlineStart
|
||||||
|
}
|
||||||
|
to -> {
|
||||||
|
openMarker = false
|
||||||
|
underlineEnd
|
||||||
|
}
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.append(mark)
|
||||||
|
|
||||||
|
if (isEndOfLine(c.toInt()) && openMarker) {
|
||||||
|
lines.append(underlineEnd + c + underlineStart)
|
||||||
|
} else {
|
||||||
|
lines.append(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.toString()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user