1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-14 03:35:37 +02:00

Bug 481126 - Hook up QML content assist to tern.js-based analyzer

Also renames Activator.

Change-Id: I58161a40b0caa2930e4fb2a5b2a70748fbe552ae
This commit is contained in:
Doug Schaefer 2015-12-02 20:28:23 -05:00 committed by Gerrit Code Review @ Eclipse.org
parent 241a60fe8a
commit f1a21f5c64
25 changed files with 1526 additions and 378 deletions

View file

@ -3,6 +3,7 @@ package org.eclipse.cdt.qt.core.tests;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public class Activator implements BundleActivator {
@ -22,4 +23,9 @@ public class Activator implements BundleActivator {
return context != null ? context.getBundle() : null;
}
public static <T> T getService(Class<T> service) {
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
}

View file

@ -3,24 +3,14 @@ package org.eclipse.cdt.qt.core.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.eclipse.cdt.internal.qt.core.qml.QMLAnalyzer;
import org.eclipse.cdt.internal.qt.core.qml.QMLAnalyzer.RequestCallback;
import org.eclipse.cdt.qt.core.QMLAnalyzer;
import org.eclipse.cdt.qt.core.QMLTernCompletion;
import org.junit.BeforeClass;
import org.junit.Test;
@ -28,292 +18,209 @@ import org.junit.Test;
public class NashornTests {
protected static QMLAnalyzer analyzer;
protected static ScriptEngine engine;
protected static Invocable invoke;
private static Object load(ScriptEngine engine, String file) throws Throwable {
URL scriptURL = Activator.getBundle().getEntry(file);
if (scriptURL == null) {
throw new FileNotFoundException(file);
}
engine.getContext().setAttribute(ScriptEngine.FILENAME, file, ScriptContext.ENGINE_SCOPE);
return engine.eval(new BufferedReader(new InputStreamReader(scriptURL.openStream())));
}
@BeforeClass
public static void loadAnalyzer() {
System.out.println("Loading QML Analyzer...");
long start = System.currentTimeMillis();
analyzer = new QMLAnalyzer();
try {
analyzer.load();
} catch (ScriptException | IOException e) {
e.printStackTrace();
return;
}
engine = analyzer.getEngine();
invoke = analyzer.getInvocable();
long stop = System.currentTimeMillis();
System.out.println("Loaded: " + (stop - start) + " ms.");
analyzer = Activator.getService(QMLAnalyzer.class);
}
protected Bindings newObject() throws Throwable {
return (Bindings) engine.eval("new Object()");
}
protected Bindings newArray() throws Throwable {
return (Bindings) engine.eval("new Array()");
}
protected Object createTernServer() throws Throwable {
Bindings options = newObject();
options.put("ecmaVersion", 5);
Bindings plugins = newObject();
plugins.put("qml", true);
options.put("plugins", plugins);
Bindings defs = newArray();
load(engine, "scripts/ecma5-defs.js");
invoke.invokeMethod(defs, "push", engine.get("ecma5defs"));
options.put("defs", defs);
return analyzer.createTernServer(options);
}
private static class Completion {
final String name;
final String type;
final String origin;
public Completion(String name, String type, String origin) {
this.name = name;
this.type = type;
this.origin = origin;
}
}
protected void getCompletions(Object server, String code, Completion... expected) throws Throwable {
protected void getCompletions(String code, QMLTernCompletion... expected) throws Throwable {
int pos = code.indexOf('|');
code = code.substring(0, pos) + code.substring(pos + 1);
invoke.invokeMethod(server, "addFile", "test1.qml", code);
analyzer.addFile("test1.qml", code);
Bindings query = engine.createBindings();
query.put("type", "completions");
query.put("file", "test1.qml");
query.put("end", pos);
query.put("types", true);
query.put("docs", false);
query.put("urls", false);
query.put("origins", true);
query.put("caseInsensitive", true);
query.put("lineCharPositions", true);
query.put("expandWordForward", false);
query.put("guess", false);
Bindings request = engine.createBindings();
request.put("query", query);
Collection<QMLTernCompletion> QMLTernCompletions = analyzer.getCompletions("test1.qml", pos);
RequestCallback callback = (err, data) -> {
if (err != null) {
fail(err.toString());
Map<String, QMLTernCompletion> set = new HashMap<>();
Set<String> unexpected = new HashSet<>();
for (QMLTernCompletion QMLTernCompletion : expected) {
set.put(QMLTernCompletion.getName(), QMLTernCompletion);
}
for (QMLTernCompletion QMLTernCompletion : QMLTernCompletions) {
String name = QMLTernCompletion.getName();
QMLTernCompletion c = set.get(name);
if (c != null) {
assertEquals(c.getType(), QMLTernCompletion.getType());
assertEquals(c.getOrigin(), QMLTernCompletion.getOrigin());
set.remove(name);
} else {
try {
Bindings[] completions = (Bindings[]) invoke.invokeMethod(engine.get("Java"), "to",
((Bindings) data).get("completions"), "javax.script.Bindings[]");
Map<String, Completion> set = new HashMap<>();
Set<String> unexpected = new HashSet<>();
for (Completion completion : expected) {
set.put(completion.name, completion);
}
for (Bindings completion : completions) {
String name = (String) completion.get("name");
Completion c = set.get(name);
if (c != null) {
assertEquals(c.type, completion.get("type"));
assertEquals(c.origin, completion.get("origin"));
set.remove(name);
} else {
unexpected.add(name);
}
}
if (!set.isEmpty()) {
fail("Missing names: " + String.join(", ", set.keySet()));
}
if (!unexpected.isEmpty()) {
fail("Unexpected names: " + String.join(", ", unexpected));
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
unexpected.add(name);
}
};
invoke.invokeMethod(server, "request", request, invoke.invokeFunction("requestCallback", callback));
}
if (!set.isEmpty()) {
fail("Missing names: " + String.join(", ", set.keySet()));
}
if (!unexpected.isEmpty()) {
fail("Unexpected names: " + String.join(", ", unexpected));
}
}
@Test
public void test1() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\tproperty int height\n\the|\n}",
new Completion("height", "number", "test1.qml"));
getCompletions("Window {\n\tproperty int height\n\the|\n}",
new QMLTernCompletion("height", "number", "test1.qml"));
}
@Test
public void test2() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(),
"Window {\n\tproperty int height\n\tproperty int width\n\tproperty string text\n\t|\n}",
new Completion("height", "number", "test1.qml"), new Completion("text", "string", "test1.qml"),
new Completion("width", "number", "test1.qml"));
getCompletions("Window {\n\tproperty int height\n\tproperty int width\n\tproperty string text\n\t|\n}",
new QMLTernCompletion("height", "number", "test1.qml"),
new QMLTernCompletion("text", "string", "test1.qml"),
new QMLTernCompletion("width", "number", "test1.qml"));
}
@Test
public void test3() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\tproperty int height\n\tObject {\n\t\t|\n\t}\n}");
getCompletions("Window {\n\tproperty int height\n\tObject {\n\t\t|\n\t}\n}");
}
@Test
public void test4() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\tproperty var test: |\n}",
new Completion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("eval", "fn(code: string)", "ecma5"),
new Completion("isFinite", "fn(value: number) -> bool", "ecma5"),
new Completion("isNaN", "fn(value: number) -> bool", "ecma5"),
new Completion("parseFloat", "fn(string: string) -> number", "ecma5"),
new Completion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new Completion("test", "?", "test1.qml"), new Completion("undefined", "?", "ecma5"),
new Completion("Array", "fn(size: number)", "ecma5"),
new Completion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new Completion("Date", "fn(ms: number)", "ecma5"),
new Completion("Error", "fn(message: string)", "ecma5"),
new Completion("EvalError", "fn(message: string)", "ecma5"),
new Completion("Function", "fn(body: string) -> fn()", "ecma5"),
new Completion("Infinity", "number", "ecma5"), new Completion("JSON", "JSON", "ecma5"),
new Completion("Math", "Math", "ecma5"), new Completion("NaN", "number", "ecma5"),
new Completion("Number", "fn(value: ?) -> number", "ecma5"), new Completion("Object", "fn()", "ecma5"),
new Completion("RangeError", "fn(message: string)", "ecma5"),
new Completion("ReferenceError", "fn(message: string)", "ecma5"),
new Completion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new Completion("String", "fn(value: ?) -> string", "ecma5"),
new Completion("SyntaxError", "fn(message: string)", "ecma5"),
new Completion("TypeError", "fn(message: string)", "ecma5"),
new Completion("URIError", "fn(message: string)", "ecma5"));
getCompletions("Window {\n\tproperty var test: |\n}",
new QMLTernCompletion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("eval", "fn(code: string)", "ecma5"),
new QMLTernCompletion("isFinite", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("isNaN", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("parseFloat", "fn(string: string) -> number", "ecma5"),
new QMLTernCompletion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new QMLTernCompletion("test", "?", "test1.qml"), new QMLTernCompletion("undefined", "?", "ecma5"),
new QMLTernCompletion("Array", "fn(size: number)", "ecma5"),
new QMLTernCompletion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new QMLTernCompletion("Date", "fn(ms: number)", "ecma5"),
new QMLTernCompletion("Error", "fn(message: string)", "ecma5"),
new QMLTernCompletion("EvalError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("Function", "fn(body: string) -> fn()", "ecma5"),
new QMLTernCompletion("Infinity", "number", "ecma5"), new QMLTernCompletion("JSON", "JSON", "ecma5"),
new QMLTernCompletion("Math", "Math", "ecma5"), new QMLTernCompletion("NaN", "number", "ecma5"),
new QMLTernCompletion("Number", "fn(value: ?) -> number", "ecma5"),
new QMLTernCompletion("Object", "fn()", "ecma5"),
new QMLTernCompletion("RangeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("ReferenceError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new QMLTernCompletion("String", "fn(value: ?) -> string", "ecma5"),
new QMLTernCompletion("SyntaxError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("TypeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("URIError", "fn(message: string)", "ecma5"));
}
@Test
public void test5() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\ttest: |\n}",
new Completion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("eval", "fn(code: string)", "ecma5"),
new Completion("isFinite", "fn(value: number) -> bool", "ecma5"),
new Completion("isNaN", "fn(value: number) -> bool", "ecma5"),
new Completion("parseFloat", "fn(string: string) -> number", "ecma5"),
new Completion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new Completion("undefined", "?", "ecma5"), new Completion("Array", "fn(size: number)", "ecma5"),
new Completion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new Completion("Date", "fn(ms: number)", "ecma5"),
new Completion("Error", "fn(message: string)", "ecma5"),
new Completion("EvalError", "fn(message: string)", "ecma5"),
new Completion("Function", "fn(body: string) -> fn()", "ecma5"),
new Completion("Infinity", "number", "ecma5"), new Completion("JSON", "JSON", "ecma5"),
new Completion("Math", "Math", "ecma5"), new Completion("NaN", "number", "ecma5"),
new Completion("Number", "fn(value: ?) -> number", "ecma5"), new Completion("Object", "fn()", "ecma5"),
new Completion("RangeError", "fn(message: string)", "ecma5"),
new Completion("ReferenceError", "fn(message: string)", "ecma5"),
new Completion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new Completion("String", "fn(value: ?) -> string", "ecma5"),
new Completion("SyntaxError", "fn(message: string)", "ecma5"),
new Completion("TypeError", "fn(message: string)", "ecma5"),
new Completion("URIError", "fn(message: string)", "ecma5"));
getCompletions("Window {\n\ttest: |\n}",
new QMLTernCompletion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("eval", "fn(code: string)", "ecma5"),
new QMLTernCompletion("isFinite", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("isNaN", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("parseFloat", "fn(string: string) -> number", "ecma5"),
new QMLTernCompletion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new QMLTernCompletion("undefined", "?", "ecma5"),
new QMLTernCompletion("Array", "fn(size: number)", "ecma5"),
new QMLTernCompletion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new QMLTernCompletion("Date", "fn(ms: number)", "ecma5"),
new QMLTernCompletion("Error", "fn(message: string)", "ecma5"),
new QMLTernCompletion("EvalError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("Function", "fn(body: string) -> fn()", "ecma5"),
new QMLTernCompletion("Infinity", "number", "ecma5"), new QMLTernCompletion("JSON", "JSON", "ecma5"),
new QMLTernCompletion("Math", "Math", "ecma5"), new QMLTernCompletion("NaN", "number", "ecma5"),
new QMLTernCompletion("Number", "fn(value: ?) -> number", "ecma5"),
new QMLTernCompletion("Object", "fn()", "ecma5"),
new QMLTernCompletion("RangeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("ReferenceError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new QMLTernCompletion("String", "fn(value: ?) -> string", "ecma5"),
new QMLTernCompletion("SyntaxError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("TypeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("URIError", "fn(message: string)", "ecma5"));
}
@Test
public void test6() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\ttest: {\n\t\t|\n\t}\n}",
new Completion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("eval", "fn(code: string)", "ecma5"),
new Completion("isFinite", "fn(value: number) -> bool", "ecma5"),
new Completion("isNaN", "fn(value: number) -> bool", "ecma5"),
new Completion("parseFloat", "fn(string: string) -> number", "ecma5"),
new Completion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new Completion("undefined", "?", "ecma5"), new Completion("Array", "fn(size: number)", "ecma5"),
new Completion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new Completion("Date", "fn(ms: number)", "ecma5"),
new Completion("Error", "fn(message: string)", "ecma5"),
new Completion("EvalError", "fn(message: string)", "ecma5"),
new Completion("Function", "fn(body: string) -> fn()", "ecma5"),
new Completion("Infinity", "number", "ecma5"), new Completion("JSON", "JSON", "ecma5"),
new Completion("Math", "Math", "ecma5"), new Completion("NaN", "number", "ecma5"),
new Completion("Number", "fn(value: ?) -> number", "ecma5"), new Completion("Object", "fn()", "ecma5"),
new Completion("RangeError", "fn(message: string)", "ecma5"),
new Completion("ReferenceError", "fn(message: string)", "ecma5"),
new Completion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new Completion("String", "fn(value: ?) -> string", "ecma5"),
new Completion("SyntaxError", "fn(message: string)", "ecma5"),
new Completion("TypeError", "fn(message: string)", "ecma5"),
new Completion("URIError", "fn(message: string)", "ecma5"));
getCompletions("Window {\n\ttest: {\n\t\t|\n\t}\n}",
new QMLTernCompletion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("eval", "fn(code: string)", "ecma5"),
new QMLTernCompletion("isFinite", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("isNaN", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("parseFloat", "fn(string: string) -> number", "ecma5"),
new QMLTernCompletion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new QMLTernCompletion("undefined", "?", "ecma5"),
new QMLTernCompletion("Array", "fn(size: number)", "ecma5"),
new QMLTernCompletion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new QMLTernCompletion("Date", "fn(ms: number)", "ecma5"),
new QMLTernCompletion("Error", "fn(message: string)", "ecma5"),
new QMLTernCompletion("EvalError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("Function", "fn(body: string) -> fn()", "ecma5"),
new QMLTernCompletion("Infinity", "number", "ecma5"), new QMLTernCompletion("JSON", "JSON", "ecma5"),
new QMLTernCompletion("Math", "Math", "ecma5"), new QMLTernCompletion("NaN", "number", "ecma5"),
new QMLTernCompletion("Number", "fn(value: ?) -> number", "ecma5"),
new QMLTernCompletion("Object", "fn()", "ecma5"),
new QMLTernCompletion("RangeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("ReferenceError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new QMLTernCompletion("String", "fn(value: ?) -> string", "ecma5"),
new QMLTernCompletion("SyntaxError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("TypeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("URIError", "fn(message: string)", "ecma5"));
}
@Test
public void test7() throws Throwable {
if (engine == null) {
if (analyzer == null) {
return;
}
getCompletions(createTernServer(), "Window {\n\tfunction test() {\n\t\t|\n\t}\n}",
new Completion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new Completion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new Completion("eval", "fn(code: string)", "ecma5"),
new Completion("isFinite", "fn(value: number) -> bool", "ecma5"),
new Completion("isNaN", "fn(value: number) -> bool", "ecma5"),
new Completion("parseFloat", "fn(string: string) -> number", "ecma5"),
new Completion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new Completion("test", "fn()", "test1.qml"), new Completion("undefined", "?", "ecma5"),
new Completion("Array", "fn(size: number)", "ecma5"),
new Completion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new Completion("Date", "fn(ms: number)", "ecma5"),
new Completion("Error", "fn(message: string)", "ecma5"),
new Completion("EvalError", "fn(message: string)", "ecma5"),
new Completion("Function", "fn(body: string) -> fn()", "ecma5"),
new Completion("Infinity", "number", "ecma5"), new Completion("JSON", "JSON", "ecma5"),
new Completion("Math", "Math", "ecma5"), new Completion("NaN", "number", "ecma5"),
new Completion("Number", "fn(value: ?) -> number", "ecma5"), new Completion("Object", "fn()", "ecma5"),
new Completion("RangeError", "fn(message: string)", "ecma5"),
new Completion("ReferenceError", "fn(message: string)", "ecma5"),
new Completion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new Completion("String", "fn(value: ?) -> string", "ecma5"),
new Completion("SyntaxError", "fn(message: string)", "ecma5"),
new Completion("TypeError", "fn(message: string)", "ecma5"),
new Completion("URIError", "fn(message: string)", "ecma5"));
getCompletions("Window {\n\tfunction test() {\n\t\t|\n\t}\n}",
new QMLTernCompletion("decodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("decodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURI", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("encodeURIComponent", "fn(uri: string) -> string", "ecma5"),
new QMLTernCompletion("eval", "fn(code: string)", "ecma5"),
new QMLTernCompletion("isFinite", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("isNaN", "fn(value: number) -> bool", "ecma5"),
new QMLTernCompletion("parseFloat", "fn(string: string) -> number", "ecma5"),
new QMLTernCompletion("parseInt", "fn(string: string, radix?: number) -> number", "ecma5"),
new QMLTernCompletion("test", "fn()", "test1.qml"), new QMLTernCompletion("undefined", "?", "ecma5"),
new QMLTernCompletion("Array", "fn(size: number)", "ecma5"),
new QMLTernCompletion("Boolean", "fn(value: ?) -> bool", "ecma5"),
new QMLTernCompletion("Date", "fn(ms: number)", "ecma5"),
new QMLTernCompletion("Error", "fn(message: string)", "ecma5"),
new QMLTernCompletion("EvalError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("Function", "fn(body: string) -> fn()", "ecma5"),
new QMLTernCompletion("Infinity", "number", "ecma5"), new QMLTernCompletion("JSON", "JSON", "ecma5"),
new QMLTernCompletion("Math", "Math", "ecma5"), new QMLTernCompletion("NaN", "number", "ecma5"),
new QMLTernCompletion("Number", "fn(value: ?) -> number", "ecma5"),
new QMLTernCompletion("Object", "fn()", "ecma5"),
new QMLTernCompletion("RangeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("ReferenceError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("RegExp", "fn(source: string, flags?: string)", "ecma5"),
new QMLTernCompletion("String", "fn(value: ?) -> string", "ecma5"),
new QMLTernCompletion("SyntaxError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("TypeError", "fn(message: string)", "ecma5"),
new QMLTernCompletion("URIError", "fn(message: string)", "ecma5"));
}
}

View file

@ -27,5 +27,4 @@ Export-Package: org.eclipse.cdt.internal.qt.core;x-friends:="org.eclipse.cdt.qt.
org.eclipse.cdt.internal.qt.core.index;x-friends:="org.eclipse.cdt.qt.ui.tests",
org.eclipse.cdt.internal.qt.core.parser;x-friends:="org.eclipse.cdt.qt.ui",
org.eclipse.cdt.internal.qt.core.project;x-friends:="org.eclipse.cdt.qt.ui",
org.eclipse.cdt.internal.qt.core.qml;x-friends:="org.eclipse.cdt.qt.core.tests",
org.eclipse.cdt.qt.core

View file

@ -7,15 +7,22 @@
*/
package org.eclipse.cdt.internal.qt.core;
import java.io.IOException;
import javax.script.ScriptException;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.internal.qt.core.build.QtBuildConfigurationFactory;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.cdt.qt.core.QMLAnalyzer;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@ -56,6 +63,20 @@ public class Activator extends Plugin {
context.registerService(IQtInstallManager.class, new QtInstallManager(), null);
QMLAnalyzer qmlAnalyzer = new QMLAnalyzer();
context.registerService(QMLAnalyzer.class, qmlAnalyzer, null);
new Job("Load QML Analyzer") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
qmlAnalyzer.load();
return Status.OK_STATUS;
} catch (NoSuchMethodException | ScriptException | IOException e) {
return new Status(IStatus.ERROR, ID, "loading QML analyzer", e);
}
}
}.schedule();
configCleanup = new QtBuildConfigurationFactory.Cleanup();
ResourcesPlugin.getWorkspace().addResourceChangeListener(configCleanup);
}

View file

@ -1,77 +0,0 @@
package org.eclipse.cdt.internal.qt.core.qml;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.eclipse.cdt.internal.qt.core.Activator;
@SuppressWarnings("nls")
public class QMLAnalyzer {
private final ScriptEngine engine;
public QMLAnalyzer() {
engine = new ScriptEngineManager().getEngineByName("nashorn");
ScriptContext context = engine.getContext();
context.setWriter(new OutputStreamWriter(System.out));
context.setErrorWriter(new OutputStreamWriter(System.err));
}
public void load() throws ScriptException, IOException {
load("/tern-qml/node_modules/acorn/dist/acorn.js");
load("/tern-qml/node_modules/acorn/dist/acorn_loose.js");
load("/tern-qml/node_modules/acorn/dist/walk.js");
load("/tern-qml/node_modules/acorn-qml/inject.js");
load("/tern-qml/node_modules/acorn-qml/index.js");
load("/tern-qml/node_modules/acorn-qml/loose/inject.js");
load("/tern-qml/node_modules/acorn-qml/loose/index.js");
load("/tern-qml/node_modules/acorn-qml/walk/index.js");
load("/tern-qml/node_modules/tern/lib/signal.js");
load("/tern-qml/node_modules/tern/lib/tern.js");
load("/tern-qml/node_modules/tern/lib/def.js");
load("/tern-qml/node_modules/tern/lib/comment.js");
load("/tern-qml/node_modules/tern/lib/infer.js");
load("/tern-qml/qml.js");
load("/tern-qml/qml-nsh.js");
}
public Object load(String file) throws ScriptException, IOException {
URL scriptURL = Activator.getDefault().getBundle().getEntry(file);
if (scriptURL == null) {
throw new FileNotFoundException(file);
}
engine.getContext().setAttribute(ScriptEngine.FILENAME, file, ScriptContext.ENGINE_SCOPE);
return engine.eval(new BufferedReader(new InputStreamReader(scriptURL.openStream())));
}
public ScriptEngine getEngine() {
return engine;
}
public Invocable getInvocable() {
return (Invocable) engine;
}
public Object createTernServer(Object options) throws NoSuchMethodException, ScriptException {
return getInvocable().invokeFunction("newTernServer", options);
}
public interface RequestCallback {
void callback(Bindings err, Bindings data);
}
}

View file

@ -0,0 +1,147 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.qt.core;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.eclipse.cdt.internal.qt.core.Activator;
@SuppressWarnings("nls")
public class QMLAnalyzer {
private ScriptEngine engine;
private Invocable invoke;
private Object tern;
public void load() throws ScriptException, IOException, NoSuchMethodException {
engine = new ScriptEngineManager().getEngineByName("nashorn");
invoke = (Invocable) engine;
load("/tern-qml/node_modules/acorn/dist/acorn.js");
load("/tern-qml/node_modules/acorn/dist/acorn_loose.js");
load("/tern-qml/node_modules/acorn/dist/walk.js");
load("/tern-qml/node_modules/acorn-qml/inject.js");
load("/tern-qml/node_modules/acorn-qml/index.js");
load("/tern-qml/node_modules/acorn-qml/loose/inject.js");
load("/tern-qml/node_modules/acorn-qml/loose/index.js");
load("/tern-qml/node_modules/acorn-qml/walk/index.js");
load("/tern-qml/node_modules/tern/lib/signal.js");
load("/tern-qml/node_modules/tern/lib/tern.js");
load("/tern-qml/node_modules/tern/lib/def.js");
load("/tern-qml/node_modules/tern/lib/comment.js");
load("/tern-qml/node_modules/tern/lib/infer.js");
load("/tern-qml/qml.js");
load("/tern-qml/qml-nsh.js");
Bindings options = (Bindings) engine.eval("new Object()");
options.put("ecmaVersion", 5);
Bindings plugins = (Bindings) engine.eval("new Object()");
plugins.put("qml", true);
options.put("plugins", plugins);
Bindings defs = (Bindings) engine.eval("new Array()");
load("/tern-qml/ecma5-defs.js");
invoke.invokeMethod(defs, "push", engine.get("ecma5defs"));
options.put("defs", defs);
synchronized (this) {
tern = invoke.invokeFunction("newTernServer", options);
notifyAll();
}
}
private Object load(String file) throws ScriptException, IOException {
URL scriptURL = Activator.getDefault().getBundle().getEntry(file);
if (scriptURL == null) {
throw new FileNotFoundException(file);
}
engine.getContext().setAttribute(ScriptEngine.FILENAME, file, ScriptContext.ENGINE_SCOPE);
return engine.eval(new BufferedReader(new InputStreamReader(scriptURL.openStream())));
}
private void waitUntilLoaded() {
synchronized (this) {
while (tern == null) {
try {
wait();
} catch (InterruptedException e) {
Activator.log(e);
return;
}
}
}
}
public interface RequestCallback {
void callback(Object err, Object data);
}
public void addFile(String fileName, String code) throws NoSuchMethodException, ScriptException {
waitUntilLoaded();
invoke.invokeMethod(tern, "addFile", fileName, code);
}
public Collection<QMLTernCompletion> getCompletions(String fileName, int pos)
throws NoSuchMethodException, ScriptException {
waitUntilLoaded();
Bindings query = engine.createBindings();
query.put("type", "completions");
query.put("file", fileName);
query.put("end", pos);
query.put("types", true);
query.put("docs", false);
query.put("urls", false);
query.put("origins", true);
query.put("caseInsensitive", true);
query.put("lineCharPositions", true);
query.put("expandWordForward", false);
query.put("includeKeywords", true);
query.put("guess", false);
Bindings request = engine.createBindings();
request.put("query", query);
List<QMLTernCompletion> completions = new ArrayList<>();
RequestCallback callback = (err, data) -> {
if (err != null) {
throw new RuntimeException(err.toString());
} else {
try {
for (Bindings completion : (Bindings[]) invoke.invokeMethod(engine.get("Java"), "to",
((Bindings) data).get("completions"), "javax.script.Bindings[]")) {
completions.add(new QMLTernCompletion((String) completion.get("name"),
(String) completion.get("type"), (String) completion.get("origin")));
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
};
invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));
return completions;
}
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.qt.core;
public class QMLTernCompletion {
private final String name;
private final String type;
private final String origin;
public QMLTernCompletion(String name, String type, String origin) {
this.name = name;
this.type = type;
this.origin = origin;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public String getOrigin() {
return origin;
}
}

View file

@ -0,0 +1,975 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
ecma5defs = {
"!name": "ecma5",
"!define": {
"Error.prototype": "Error.prototype"
},
"Infinity": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Infinity",
"!doc": "A numeric value representing infinity."
},
"undefined": {
"!type": "?",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/undefined",
"!doc": "The value undefined."
},
"NaN": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/NaN",
"!doc": "A value representing Not-A-Number."
},
"Object": {
"!type": "fn()",
"getPrototypeOf": {
"!type": "fn(obj: ?) -> ?",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getPrototypeOf",
"!doc": "Returns the prototype (i.e. the internal prototype) of the specified object."
},
"create": {
"!type": "fn(proto: ?) -> !custom:Object_create",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create",
"!doc": "Creates a new object with the specified prototype object and properties."
},
"defineProperty": {
"!type": "fn(obj: ?, prop: string, desc: ?) -> !custom:Object_defineProperty",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty",
"!doc": "Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article."
},
"defineProperties": {
"!type": "fn(obj: ?, props: ?) -> !custom:Object_defineProperties",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty",
"!doc": "Defines a new property directly on an object, or modifies an existing property on an object, and returns the object. If you want to see how to use the Object.defineProperty method with a binary-flags-like syntax, see this article."
},
"getOwnPropertyDescriptor": {
"!type": "fn(obj: ?, prop: string) -> ?",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor",
"!doc": "Returns a property descriptor for an own property (that is, one directly present on an object, not present by dint of being along an object's prototype chain) of a given object."
},
"keys": {
"!type": "fn(obj: ?) -> [string]",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys",
"!doc": "Returns an array of a given object's own enumerable properties, in the same order as that provided by a for-in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well)."
},
"getOwnPropertyNames": {
"!type": "fn(obj: ?) -> [string]",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames",
"!doc": "Returns an array of all properties (enumerable or not) found directly upon a given object."
},
"seal": {
"!type": "fn(obj: ?)",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/seal",
"!doc": "Seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable."
},
"isSealed": {
"!type": "fn(obj: ?) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isSealed",
"!doc": "Determine if an object is sealed."
},
"freeze": {
"!type": "fn(obj: ?) -> !0",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/freeze",
"!doc": "Freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen."
},
"isFrozen": {
"!type": "fn(obj: ?) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/isFrozen",
"!doc": "Determine if an object is frozen."
},
"preventExtensions": {
"!type": "fn(obj: ?)",
"!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions",
"!doc": "Prevents new properties from ever being added to an object."
},
"isExtensible": {
"!type": "fn(obj: ?) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible",
"!doc": "The Object.isExtensible() method determines if an object is extensible (whether it can have new properties added to it)."
},
"prototype": {
"!stdProto": "Object",
"toString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString",
"!doc": "Returns a string representing the object."
},
"toLocaleString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toLocaleString",
"!doc": "Returns a string representing the object. This method is meant to be overriden by derived objects for locale-specific purposes."
},
"valueOf": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/valueOf",
"!doc": "Returns the primitive value of the specified object"
},
"hasOwnProperty": {
"!type": "fn(prop: string) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty",
"!doc": "Returns a boolean indicating whether the object has the specified property."
},
"propertyIsEnumerable": {
"!type": "fn(prop: string) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable",
"!doc": "Returns a Boolean indicating whether the specified property is enumerable."
},
"isPrototypeOf": {
"!type": "fn(obj: ?) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf",
"!doc": "Tests for an object in another object's prototype chain."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object",
"!doc": "Creates an object wrapper."
},
"Function": {
"!type": "fn(body: string) -> fn()",
"prototype": {
"!stdProto": "Function",
"apply": {
"!type": "fn(this: ?, args: [?])",
"!effects": [
"call and return !this this=!0 !1.<i> !1.<i> !1.<i>"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply",
"!doc": "Calls a function with a given this value and arguments provided as an array (or an array like object)."
},
"call": {
"!type": "fn(this: ?, args?: ?) -> !this.!ret",
"!effects": [
"call and return !this this=!0 !1 !2 !3 !4"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call",
"!doc": "Calls a function with a given this value and arguments provided individually."
},
"bind": {
"!type": "fn(this: ?, args?: ?) -> !custom:Function_bind",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind",
"!doc": "Creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function was called."
},
"prototype": "?"
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function",
"!doc": "Every function in JavaScript is actually a Function object."
},
"Array": {
"!type": "fn(size: number) -> !custom:Array_ctor",
"isArray": {
"!type": "fn(value: ?) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray",
"!doc": "Returns true if an object is an array, false if it is not."
},
"prototype": {
"!stdProto": "Array",
"length": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/length",
"!doc": "An unsigned, 32-bit integer that specifies the number of elements in an array."
},
"concat": {
"!type": "fn(other: [?]) -> !this",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/concat",
"!doc": "Returns a new array comprised of this array joined with other array(s) and/or value(s)."
},
"join": {
"!type": "fn(separator?: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/join",
"!doc": "Joins all elements of an array into a string."
},
"splice": {
"!type": "fn(pos: number, amount: number)",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice",
"!doc": "Changes the content of an array, adding new elements while removing old elements."
},
"pop": {
"!type": "fn() -> !this.<i>",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/pop",
"!doc": "Removes the last element from an array and returns that element."
},
"push": {
"!type": "fn(newelt: ?) -> number",
"!effects": [
"propagate !0 !this.<i>"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/push",
"!doc": "Mutates an array by appending the given elements and returning the new length of the array."
},
"shift": {
"!type": "fn() -> !this.<i>",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/shift",
"!doc": "Removes the first element from an array and returns that element. This method changes the length of the array."
},
"unshift": {
"!type": "fn(newelt: ?) -> number",
"!effects": [
"propagate !0 !this.<i>"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/unshift",
"!doc": "Adds one or more elements to the beginning of an array and returns the new length of the array."
},
"slice": {
"!type": "fn(from: number, to?: number) -> !this",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice",
"!doc": "Returns a shallow copy of a portion of an array."
},
"reverse": {
"!type": "fn()",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/reverse",
"!doc": "Reverses an array in place. The first array element becomes the last and the last becomes the first."
},
"sort": {
"!type": "fn(compare?: fn(a: ?, b: ?) -> number)",
"!effects": [
"call !0 !this.<i> !this.<i>"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort",
"!doc": "Sorts the elements of an array in place and returns the array."
},
"indexOf": {
"!type": "fn(elt: ?, from?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf",
"!doc": "Returns the first index at which a given element can be found in the array, or -1 if it is not present."
},
"lastIndexOf": {
"!type": "fn(elt: ?, from?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/lastIndexOf",
"!doc": "Returns the last index at which a given element can be found in the array, or -1 if it is not present. The array is searched backwards, starting at fromIndex."
},
"every": {
"!type": "fn(test: fn(elt: ?, i: number) -> bool, context?: ?) -> bool",
"!effects": [
"call !0 this=!1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/every",
"!doc": "Tests whether all elements in the array pass the test implemented by the provided function."
},
"some": {
"!type": "fn(test: fn(elt: ?, i: number) -> bool, context?: ?) -> bool",
"!effects": [
"call !0 this=!1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/some",
"!doc": "Tests whether some element in the array passes the test implemented by the provided function."
},
"filter": {
"!type": "fn(test: fn(elt: ?, i: number) -> bool, context?: ?) -> !this",
"!effects": [
"call !0 this=!1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter",
"!doc": "Creates a new array with all elements that pass the test implemented by the provided function."
},
"forEach": {
"!type": "fn(f: fn(elt: ?, i: number), context?: ?)",
"!effects": [
"call !0 this=!1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach",
"!doc": "Executes a provided function once per array element."
},
"map": {
"!type": "fn(f: fn(elt: ?, i: number) -> ?, context?: ?) -> [!0.!ret]",
"!effects": [
"call !0 this=!1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map",
"!doc": "Creates a new array with the results of calling a provided function on every element in this array."
},
"reduce": {
"!type": "fn(combine: fn(sum: ?, elt: ?, i: number) -> ?, init?: ?) -> !0.!ret",
"!effects": [
"call !0 !1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce",
"!doc": "Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value."
},
"reduceRight": {
"!type": "fn(combine: fn(sum: ?, elt: ?, i: number) -> ?, init?: ?) -> !0.!ret",
"!effects": [
"call !0 !1 !this.<i> number"
],
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/ReduceRight",
"!doc": "Apply a function simultaneously against two values of the array (from right-to-left) as to reduce it to a single value."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array",
"!doc": "The JavaScript Array global object is a constructor for arrays, which are high-level, list-like objects."
},
"String": {
"!type": "fn(value: ?) -> string",
"fromCharCode": {
"!type": "fn(code: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/fromCharCode",
"!doc": "Returns a string created by using the specified sequence of Unicode values."
},
"prototype": {
"!stdProto": "String",
"length": {
"!type": "number",
"!url": "https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/length",
"!doc": "Represents the length of a string."
},
"<i>": "string",
"charAt": {
"!type": "fn(i: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charAt",
"!doc": "Returns the specified character from a string."
},
"charCodeAt": {
"!type": "fn(i: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/charCodeAt",
"!doc": "Returns the numeric Unicode value of the character at the given index (except for unicode codepoints > 0x10000)."
},
"indexOf": {
"!type": "fn(char: string, from?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/indexOf",
"!doc": "Returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex,\nreturns -1 if the value is not found."
},
"lastIndexOf": {
"!type": "fn(char: string, from?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/lastIndexOf",
"!doc": "Returns the index within the calling String object of the last occurrence of the specified value, or -1 if not found. The calling string is searched backward, starting at fromIndex."
},
"substring": {
"!type": "fn(from: number, to?: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substring",
"!doc": "Returns a subset of a string between one index and another, or through the end of the string."
},
"substr": {
"!type": "fn(from: number, length?: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/substr",
"!doc": "Returns the characters in a string beginning at the specified location through the specified number of characters."
},
"slice": {
"!type": "fn(from: number, to?: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/slice",
"!doc": "Extracts a section of a string and returns a new string."
},
"trim": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim",
"!doc": "Removes whitespace from both ends of the string."
},
"toUpperCase": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase",
"!doc": "Returns the calling string value converted to uppercase."
},
"toLowerCase": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLowerCase",
"!doc": "Returns the calling string value converted to lowercase."
},
"toLocaleUpperCase": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase",
"!doc": "Returns the calling string value converted to upper case, according to any locale-specific case mappings."
},
"toLocaleLowerCase": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase",
"!doc": "Returns the calling string value converted to lower case, according to any locale-specific case mappings."
},
"split": {
"!type": "fn(pattern: string) -> [string]",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/split",
"!doc": "Splits a String object into an array of strings by separating the string into substrings."
},
"concat": {
"!type": "fn(other: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/concat",
"!doc": "Combines the text of two or more strings and returns a new string."
},
"localeCompare": {
"!type": "fn(other: string) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/localeCompare",
"!doc": "Returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order."
},
"match": {
"!type": "fn(pattern: +RegExp) -> [string]",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/match",
"!doc": "Used to retrieve the matches when matching a string against a regular expression."
},
"replace": {
"!type": "fn(pattern: string|+RegExp, replacement: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace",
"!doc": "Returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match."
},
"search": {
"!type": "fn(pattern: +RegExp) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/search",
"!doc": "Executes the search for a match between a regular expression and this String object."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String",
"!doc": "The String global object is a constructor for strings, or a sequence of characters."
},
"Number": {
"!type": "fn(value: ?) -> number",
"MAX_VALUE": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MAX_VALUE",
"!doc": "The maximum numeric value representable in JavaScript."
},
"MIN_VALUE": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/MIN_VALUE",
"!doc": "The smallest positive numeric value representable in JavaScript."
},
"POSITIVE_INFINITY": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY",
"!doc": "A value representing the positive Infinity value."
},
"NEGATIVE_INFINITY": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY",
"!doc": "A value representing the negative Infinity value."
},
"prototype": {
"!stdProto": "Number",
"toString": {
"!type": "fn(radix?: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString",
"!doc": "Returns a string representing the specified Number object"
},
"toFixed": {
"!type": "fn(digits: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toFixed",
"!doc": "Formats a number using fixed-point notation"
},
"toExponential": {
"!type": "fn(digits: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toExponential",
"!doc": "Returns a string representing the Number object in exponential notation"
},
"toPrecision": {
"!type": "fn(digits: number) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number/toPrecision",
"!doc": "The toPrecision() method returns a string representing the number to the specified precision."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Number",
"!doc": "The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor."
},
"Boolean": {
"!type": "fn(value: ?) -> bool",
"prototype": {
"!stdProto": "Boolean"
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Boolean",
"!doc": "The Boolean object is an object wrapper for a boolean value."
},
"RegExp": {
"!type": "fn(source: string, flags?: string)",
"prototype": {
"!stdProto": "RegExp",
"exec": {
"!type": "fn(input: string) -> [string]",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec",
"!doc": "Executes a search for a match in a specified string. Returns a result array, or null."
},
"test": {
"!type": "fn(input: string) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test",
"!doc": "Executes the search for a match between a regular expression and a specified string. Returns true or false."
},
"global": {
"!type": "bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
"!doc": "Creates a regular expression object for matching text with a pattern."
},
"ignoreCase": {
"!type": "bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
"!doc": "Creates a regular expression object for matching text with a pattern."
},
"multiline": {
"!type": "bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/multiline",
"!doc": "Reflects whether or not to search in strings across multiple lines.\n"
},
"source": {
"!type": "string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/source",
"!doc": "A read-only property that contains the text of the pattern, excluding the forward slashes.\n"
},
"lastIndex": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/lastIndex",
"!doc": "A read/write integer property that specifies the index at which to start the next match."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp",
"!doc": "Creates a regular expression object for matching text with a pattern."
},
"Date": {
"!type": "fn(ms: number)",
"parse": {
"!type": "fn(source: string) -> +Date",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/parse",
"!doc": "Parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC."
},
"UTC": {
"!type": "fn(year: number, month: number, date: number, hour?: number, min?: number, sec?: number, ms?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/UTC",
"!doc": "Accepts the same parameters as the longest form of the constructor, and returns the number of milliseconds in a Date object since January 1, 1970, 00:00:00, universal time."
},
"now": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now",
"!doc": "Returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC."
},
"prototype": {
"toUTCString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toUTCString",
"!doc": "Converts a date to a string, using the universal time convention."
},
"toISOString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString",
"!doc": "JavaScript provides a direct way to convert a date object into a string in ISO format, the ISO 8601 Extended Format."
},
"toDateString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toDateString",
"!doc": "Returns the date portion of a Date object in human readable form in American English."
},
"toTimeString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toTimeString",
"!doc": "Returns the time portion of a Date object in human readable form in American English."
},
"toLocaleDateString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleDateString",
"!doc": "Converts a date to a string, returning the \"date\" portion using the operating system's locale's conventions.\n"
},
"toLocaleTimeString": {
"!type": "fn() -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString",
"!doc": "Converts a date to a string, returning the \"time\" portion using the current locale's conventions."
},
"getTime": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTime",
"!doc": "Returns the numeric value corresponding to the time for the specified date according to universal time."
},
"getFullYear": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getFullYear",
"!doc": "Returns the year of the specified date according to local time."
},
"getYear": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getYear",
"!doc": "Returns the year in the specified date according to local time."
},
"getMonth": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMonth",
"!doc": "Returns the month in the specified date according to local time."
},
"getUTCMonth": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMonth",
"!doc": "Returns the month of the specified date according to universal time.\n"
},
"getDate": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDate",
"!doc": "Returns the day of the month for the specified date according to local time."
},
"getUTCDate": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDate",
"!doc": "Returns the day (date) of the month in the specified date according to universal time.\n"
},
"getDay": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getDay",
"!doc": "Returns the day of the week for the specified date according to local time."
},
"getUTCDay": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCDay",
"!doc": "Returns the day of the week in the specified date according to universal time.\n"
},
"getHours": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getHours",
"!doc": "Returns the hour for the specified date according to local time."
},
"getUTCHours": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCHours",
"!doc": "Returns the hours in the specified date according to universal time.\n"
},
"getMinutes": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMinutes",
"!doc": "Returns the minutes in the specified date according to local time."
},
"getUTCMinutes": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date",
"!doc": "Creates JavaScript Date instances which let you work with dates and times."
},
"getSeconds": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getSeconds",
"!doc": "Returns the seconds in the specified date according to local time."
},
"getUTCSeconds": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCSeconds",
"!doc": "Returns the seconds in the specified date according to universal time.\n"
},
"getMilliseconds": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getMilliseconds",
"!doc": "Returns the milliseconds in the specified date according to local time."
},
"getUTCMilliseconds": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds",
"!doc": "Returns the milliseconds in the specified date according to universal time.\n"
},
"getTimezoneOffset": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset",
"!doc": "Returns the time-zone offset from UTC, in minutes, for the current locale."
},
"setTime": {
"!type": "fn(date: +Date) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setTime",
"!doc": "Sets the Date object to the time represented by a number of milliseconds since January 1, 1970, 00:00:00 UTC.\n"
},
"setFullYear": {
"!type": "fn(year: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setFullYear",
"!doc": "Sets the full year for a specified date according to local time.\n"
},
"setUTCFullYear": {
"!type": "fn(year: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCFullYear",
"!doc": "Sets the full year for a specified date according to universal time.\n"
},
"setMonth": {
"!type": "fn(month: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMonth",
"!doc": "Set the month for a specified date according to local time."
},
"setUTCMonth": {
"!type": "fn(month: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMonth",
"!doc": "Sets the month for a specified date according to universal time.\n"
},
"setDate": {
"!type": "fn(day: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setDate",
"!doc": "Sets the day of the month for a specified date according to local time."
},
"setUTCDate": {
"!type": "fn(day: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCDate",
"!doc": "Sets the day of the month for a specified date according to universal time.\n"
},
"setHours": {
"!type": "fn(hour: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setHours",
"!doc": "Sets the hours for a specified date according to local time, and returns the number of milliseconds since 1 January 1970 00:00:00 UTC until the time represented by the updated Date instance."
},
"setUTCHours": {
"!type": "fn(hour: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCHours",
"!doc": "Sets the hour for a specified date according to universal time.\n"
},
"setMinutes": {
"!type": "fn(min: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMinutes",
"!doc": "Sets the minutes for a specified date according to local time."
},
"setUTCMinutes": {
"!type": "fn(min: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMinutes",
"!doc": "Sets the minutes for a specified date according to universal time.\n"
},
"setSeconds": {
"!type": "fn(sec: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setSeconds",
"!doc": "Sets the seconds for a specified date according to local time."
},
"setUTCSeconds": {
"!type": "fn(sec: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCSeconds",
"!doc": "Sets the seconds for a specified date according to universal time.\n"
},
"setMilliseconds": {
"!type": "fn(ms: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setMilliseconds",
"!doc": "Sets the milliseconds for a specified date according to local time.\n"
},
"setUTCMilliseconds": {
"!type": "fn(ms: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds",
"!doc": "Sets the milliseconds for a specified date according to universal time.\n"
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date",
"!doc": "Creates JavaScript Date instances which let you work with dates and times."
},
"Error": {
"!type": "fn(message: string)",
"prototype": {
"name": {
"!type": "string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/name",
"!doc": "A name for the type of error."
},
"message": {
"!type": "string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error/message",
"!doc": "A human-readable description of the error."
}
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error",
"!doc": "Creates an error object."
},
"SyntaxError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/SyntaxError",
"!doc": "Represents an error when trying to interpret syntactically invalid code."
},
"ReferenceError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError",
"!doc": "Represents an error when a non-existent variable is referenced."
},
"URIError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/URIError",
"!doc": "Represents an error when a malformed URI is encountered."
},
"EvalError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/EvalError",
"!doc": "Represents an error regarding the eval function."
},
"RangeError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RangeError",
"!doc": "Represents an error when a number is not within the correct range allowed."
},
"TypeError": {
"!type": "fn(message: string)",
"prototype": "Error.prototype",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/TypeError",
"!doc": "Represents an error an error when a value is not of the expected type."
},
"parseInt": {
"!type": "fn(string: string, radix?: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt",
"!doc": "Parses a string argument and returns an integer of the specified radix or base."
},
"parseFloat": {
"!type": "fn(string: string) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseFloat",
"!doc": "Parses a string argument and returns a floating point number."
},
"isNaN": {
"!type": "fn(value: number) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isNaN",
"!doc": "Determines whether a value is NaN or not. Be careful, this function is broken. You may be interested in ECMAScript 6 Number.isNaN."
},
"isFinite": {
"!type": "fn(value: number) -> bool",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/isFinite",
"!doc": "Determines whether the passed value is a finite number."
},
"eval": {
"!type": "fn(code: string) -> ?",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval",
"!doc": "Evaluates JavaScript code represented as a string."
},
"encodeURI": {
"!type": "fn(uri: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURI",
"!doc": "Encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \"surrogate\" characters)."
},
"encodeURIComponent": {
"!type": "fn(uri: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent",
"!doc": "Encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two \"surrogate\" characters)."
},
"decodeURI": {
"!type": "fn(uri: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURI",
"!doc": "Decodes a Uniform Resource Identifier (URI) previously created by encodeURI or by a similar routine."
},
"decodeURIComponent": {
"!type": "fn(uri: string) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/decodeURIComponent",
"!doc": "Decodes a Uniform Resource Identifier (URI) component previously created by encodeURIComponent or by a similar routine."
},
"Math": {
"E": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/E",
"!doc": "The base of natural logarithms, e, approximately 2.718."
},
"LN2": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN2",
"!doc": "The natural logarithm of 2, approximately 0.693."
},
"LN10": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LN10",
"!doc": "The natural logarithm of 10, approximately 2.302."
},
"LOG2E": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG2E",
"!doc": "The base 2 logarithm of E (approximately 1.442)."
},
"LOG10E": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/LOG10E",
"!doc": "The base 10 logarithm of E (approximately 0.434)."
},
"SQRT1_2": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT1_2",
"!doc": "The square root of 1/2; equivalently, 1 over the square root of 2, approximately 0.707."
},
"SQRT2": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/SQRT2",
"!doc": "The square root of 2, approximately 1.414."
},
"PI": {
"!type": "number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/PI",
"!doc": "The ratio of the circumference of a circle to its diameter, approximately 3.14159."
},
"abs": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/abs",
"!doc": "Returns the absolute value of a number."
},
"cos": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/cos",
"!doc": "Returns the cosine of a number."
},
"sin": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sin",
"!doc": "Returns the sine of a number."
},
"tan": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/tan",
"!doc": "Returns the tangent of a number."
},
"acos": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/acos",
"!doc": "Returns the arccosine (in radians) of a number."
},
"asin": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/asin",
"!doc": "Returns the arcsine (in radians) of a number."
},
"atan": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan",
"!doc": "Returns the arctangent (in radians) of a number."
},
"atan2": {
"!type": "fn(y: number, x: number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/atan2",
"!doc": "Returns the arctangent of the quotient of its arguments."
},
"ceil": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/ceil",
"!doc": "Returns the smallest integer greater than or equal to a number."
},
"floor": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/floor",
"!doc": "Returns the largest integer less than or equal to a number."
},
"round": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/round",
"!doc": "Returns the value of a number rounded to the nearest integer."
},
"exp": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/exp",
"!doc": "Returns Ex, where x is the argument, and E is Euler's constant, the base of the natural logarithms."
},
"log": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/log",
"!doc": "Returns the natural logarithm (base E) of a number."
},
"sqrt": {
"!type": "fn(number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/sqrt",
"!doc": "Returns the square root of a number."
},
"pow": {
"!type": "fn(number, number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/pow",
"!doc": "Returns base to the exponent power, that is, baseexponent."
},
"max": {
"!type": "fn(number, number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/max",
"!doc": "Returns the largest of zero or more numbers."
},
"min": {
"!type": "fn(number, number) -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/min",
"!doc": "Returns the smallest of zero or more numbers."
},
"random": {
"!type": "fn() -> number",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/random",
"!doc": "Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range."
},
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math",
"!doc": "A built-in object that has properties and methods for mathematical constants and functions."
},
"JSON": {
"parse": {
"!type": "fn(json: string) -> ?",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/parse",
"!doc": "Parse a string as JSON, optionally transforming the value produced by parsing."
},
"stringify": {
"!type": "fn(value: ?) -> string",
"!url": "https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify",
"!doc": "Convert a value to JSON, optionally replacing values if a replacer function is specified, or optionally including only the specified properties if a replacer array is specified."
},
"!url": "https://developer.mozilla.org/en-US/docs/JSON",
"!doc": "JSON (JavaScript Object Notation) is a data-interchange format. It closely resembles a subset of JavaScript syntax, although it is not a strict subset. (See JSON in the JavaScript Reference for full details.) It is useful when writing any kind of JavaScript-based application, including websites and browser extensions. For example, you might store user information in JSON format in a cookie, or you might store extension preferences in JSON in a string-valued browser preference."
}
};

View file

@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.qt.ui;singleton:=true
Bundle-Version: 2.0.0.qualifier
Bundle-Activator: org.eclipse.cdt.internal.qt.ui.QtUIPlugin
Bundle-Activator: org.eclipse.cdt.internal.qt.ui.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,

View file

@ -24,18 +24,18 @@ import org.osgi.framework.ServiceReference;
/**
* The activator class controls the plug-in life cycle
*/
public class QtUIPlugin extends AbstractUIPlugin {
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.cdt.qt.ui"; //$NON-NLS-1$
// The shared instance
private static QtUIPlugin plugin;
private static Activator plugin;
/**
* The constructor
*/
public QtUIPlugin() {
public Activator() {
}
public static Image getQtLogo() {
@ -55,7 +55,7 @@ public class QtUIPlugin extends AbstractUIPlugin {
// plugin was inactive
QtResourceChangeListener resourceManager = new QtResourceChangeListener();
ISaveParticipant saveParticipant = new QtWorkspaceSaveParticipant();
ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(QtUIPlugin.PLUGIN_ID,
ISavedState lastState = ResourcesPlugin.getWorkspace().addSaveParticipant(Activator.PLUGIN_ID,
saveParticipant);
if (lastState != null) {
lastState.processResourceChangeEvents(resourceManager);
@ -74,7 +74,7 @@ public class QtUIPlugin extends AbstractUIPlugin {
*
* @return the shared instance
*/
public static QtUIPlugin getDefault() {
public static Activator getDefault() {
return plugin;
}

View file

@ -98,7 +98,7 @@ public class QObjectConnectCompletion {
int repLength = replacement.length();
int repOffset = context.getInvocationOffset();
CCompletionProposal p
= new CCompletionProposal(replacement, repOffset, repLength, QtUIPlugin.getQtLogo(), display, relevance, context.getViewer());
= new CCompletionProposal(replacement, repOffset, repLength, Activator.getQtLogo(), display, relevance, context.getViewer());
p.setCursorPosition(repLength + cursorOffset);
return p;
}

View file

@ -52,7 +52,7 @@ public class QObjectDeclarationCompletion {
IRegion region = new Region(position.getOffset(), position.getLength());
Template template = new Template( "class", "QObject declaration", CContextType.ID, TEMPLATE, true);
return Collections.<ICompletionProposal>singletonList(new CTemplateProposal(template, tuCtx, region, QtUIPlugin.getQtLogo()));
return Collections.<ICompletionProposal>singletonList(new CTemplateProposal(template, tuCtx, region, Activator.getQtLogo()));
}
private static Position getPosition(ICEditorContentAssistInvocationContext context) {

View file

@ -27,7 +27,7 @@ import org.eclipse.jface.text.templates.TemplateContextType;
@SuppressWarnings("restriction")
public class QPropertyCompletion {
private static final String CONTEXT_ID = QtUIPlugin.PLUGIN_ID + ".proposal.Q_PROPERTY";
private static final String CONTEXT_ID = Activator.PLUGIN_ID + ".proposal.Q_PROPERTY";
private static final Template QPropertyTemplate
= new Template("Q_PROPERTY", "Q_PROPERTY declaration", CONTEXT_ID, "Q_PROPERTY( ${type} ${name} READ ${accessor} ${cursor} )", true);

View file

@ -51,7 +51,7 @@ public class QtCompletionProposalComputer extends ParsingBasedProposalComputer {
return computeCompletionProposals(cContext, completionNode, prefix);
}
} catch (Exception e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return Collections.emptyList();

View file

@ -39,7 +39,7 @@ import org.eclipse.cdt.internal.qt.core.index.IQMethod;
import org.eclipse.cdt.internal.qt.core.index.IQObject;
import org.eclipse.cdt.internal.qt.core.index.IQProperty;
import org.eclipse.cdt.internal.qt.core.index.QtIndex;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposal;
import org.eclipse.cdt.ui.text.contentassist.ICEditorContentAssistInvocationContext;
import org.eclipse.core.runtime.CoreException;
@ -64,7 +64,7 @@ public class QPropertyAttributeProposal {
int prefixLen = prefix == null ? 0 : prefix.length();
String disp = identifier.equals(display) ? display : ( identifier + " - " + display );
return new CCompletionProposal(identifier.substring(prefixLen), offset, prefixLen, QtUIPlugin.getQtLogo(), disp, relevance);
return new CCompletionProposal(identifier.substring(prefixLen), offset, prefixLen, Activator.getQtLogo(), disp, relevance);
}
private QPropertyAttributeProposal(String identifier, String display, int relevance) {
@ -145,7 +145,7 @@ public class QPropertyAttributeProposal {
try {
qobj = qtIndex.findQObject(cls.getQualifiedName());
} catch(DOMException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
if (qobj == null)
@ -468,7 +468,7 @@ public class QPropertyAttributeProposal {
return (ICPPClassType) binding.getAdapter(ICPPClassType.class);
} catch(CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return null;

View file

@ -22,7 +22,7 @@ import org.eclipse.cdt.internal.corext.template.c.CContextType;
import org.eclipse.cdt.internal.qt.core.QtKeywords;
import org.eclipse.cdt.internal.qt.core.index.IQProperty;
import org.eclipse.cdt.internal.qt.core.parser.QtParser;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
import org.eclipse.cdt.internal.ui.text.Symbols;
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposal;
@ -143,7 +143,7 @@ public class QPropertyExpansion {
try {
identifier = doc.get(begin, openingParen - begin);
} catch (BadLocationException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
if (!QtKeywords.Q_PROPERTY.equals(identifier))
@ -166,7 +166,7 @@ public class QPropertyExpansion {
else
expansion = doc.get(openingParen, context.getInvocationOffset() - openingParen );
} catch (BadLocationException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
if (expansion == null)
@ -262,7 +262,7 @@ public class QPropertyExpansion {
// Attributes without values propose only their own identifier.
if (!attribute.hasValue)
return new CCompletionProposal(attribute.identifier, context.getInvocationOffset(), 0, QtUIPlugin.getQtLogo(), attribute.identifier + " - Q_PROPERTY declaration parameter", relevance);
return new CCompletionProposal(attribute.identifier, context.getInvocationOffset(), 0, Activator.getQtLogo(), attribute.identifier + " - Q_PROPERTY declaration parameter", relevance);
// Otherwise create a template where the content depends on the type of the attribute's parameter.
String display = attribute.identifier + ' ' + attribute.paramName;
@ -377,7 +377,7 @@ public class QPropertyExpansion {
return new Identifier(begin, doc.get(begin, end - begin));
} catch(BadLocationException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return null;
}

View file

@ -7,7 +7,7 @@
*/
package org.eclipse.cdt.internal.qt.ui.assist;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.ui.text.ICCompletionProposal;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.templates.Template;
@ -24,7 +24,7 @@ public class QtTemplateProposal extends TemplateProposal implements ICCompletion
}
public QtTemplateProposal(Template template, TemplateContext context, IRegion region, int relevance) {
super(template, context, region, QtUIPlugin.getQtLogo(), BASE_RELEVANCE + relevance);
super(template, context, region, Activator.getQtLogo(), BASE_RELEVANCE + relevance);
}
@Override

View file

@ -10,7 +10,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.qt.ui.editor;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.qt.ui.text.QMLSourceViewerConfiguration;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentExtension3;
@ -20,7 +20,7 @@ import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
/**
* Basic editor for QML. Thus far has only syntax highlighting capabilities.
* Basic editor for QML. Thus far has only syntax highlighting capabilities.
*/
public class QMLEditor extends TextEditor {
public static final String EDITOR_ID = "org.eclipse.cdt.qt.ui.QMLEditor"; //$NON-NLS-1$
@ -32,8 +32,8 @@ public class QMLEditor extends TextEditor {
@Override
protected void initializeEditor() {
setPreferenceStore(QtUIPlugin.getDefault().getPreferenceStore());
setSourceViewerConfiguration(new QMLSourceViewerConfiguration());
setPreferenceStore(Activator.getDefault().getPreferenceStore());
setSourceViewerConfiguration(new QMLSourceViewerConfiguration(this));
}
@Override
@ -41,12 +41,15 @@ public class QMLEditor extends TextEditor {
super.configureSourceViewerDecorationSupport(support);
// Setup bracket matching with default color being gray
ICharacterPairMatcher matcher = new DefaultCharacterPairMatcher(BRACKETS, IDocumentExtension3.DEFAULT_PARTITIONING);
ICharacterPairMatcher matcher = new DefaultCharacterPairMatcher(BRACKETS,
IDocumentExtension3.DEFAULT_PARTITIONING);
support.setCharacterPairMatcher(matcher);
support.setMatchingCharacterPainterPreferenceKeys(BRACKET_MATCHING_PREFERENCE, BRACKET_MATCHING_COLOR_PREFERENCE);
support.setMatchingCharacterPainterPreferenceKeys(BRACKET_MATCHING_PREFERENCE,
BRACKET_MATCHING_COLOR_PREFERENCE);
IPreferenceStore store = getPreferenceStore();
store.setDefault(BRACKET_MATCHING_PREFERENCE, true);
store.setDefault(BRACKET_MATCHING_COLOR_PREFERENCE, "155,155,155"); //$NON-NLS-1$
}
}

View file

@ -17,7 +17,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.qt.ui.Messages;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.qt.core.IQtInstall;
import org.eclipse.cdt.qt.core.IQtInstallManager;
import org.eclipse.jface.dialogs.MessageDialog;
@ -52,7 +52,7 @@ public class QtPreferencePage extends PreferencePage implements IWorkbenchPrefer
@Override
public void init(IWorkbench workbench) {
manager = QtUIPlugin.getService(IQtInstallManager.class);
manager = Activator.getService(IQtInstallManager.class);
}
@Override

View file

@ -17,7 +17,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.qt.ui.editor.QtProjectFileKeyword;
import org.eclipse.cdt.internal.qt.ui.pro.parser.QtProjectFileModifier;
import org.eclipse.core.resources.IFile;
@ -71,7 +71,7 @@ public class QtProjectFileUpdateJob extends Job {
try {
proFile = findQtProjectFile(project);
} catch (CoreException e) {
QtUIPlugin.log("Unable to find Qt Project File", e); //$NON-NLS-1$
Activator.log("Unable to find Qt Project File", e); //$NON-NLS-1$
}
// We can't update a project file if it doesn't exist
@ -91,10 +91,10 @@ public class QtProjectFileUpdateJob extends Job {
modifier = new QtProjectFileModifier(document);
modifierMap.put(project, modifier);
} catch (IOException e) {
QtUIPlugin.log(e);
Activator.log(e);
break;
} catch (CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
break;
}
}
@ -149,7 +149,7 @@ public class QtProjectFileUpdateJob extends Job {
try {
file.setContents(new ByteArrayInputStream(document.get().getBytes()), 0, null);
} catch (CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
}
return Status.OK_STATUS;

View file

@ -14,7 +14,7 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.internal.qt.core.QtNature;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
@ -55,7 +55,7 @@ public class QtResourceChangeListener implements IResourceChangeListener {
return true;
}
} catch (CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return false;
} else if (resource.getType() == IResource.FOLDER) {
@ -74,7 +74,7 @@ public class QtResourceChangeListener implements IResourceChangeListener {
return true;
}
} catch (CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return false;
}
@ -104,7 +104,7 @@ public class QtResourceChangeListener implements IResourceChangeListener {
// Check all projects starting at the workspace root
event.getDelta().accept(visitor);
} catch (CoreException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
// Schedule the job to update the .pro files

View file

@ -0,0 +1,116 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.cdt.internal.qt.ui.text;
import java.util.Collection;
import javax.script.ScriptException;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.qt.ui.editor.QMLEditor;
import org.eclipse.cdt.qt.core.QMLAnalyzer;
import org.eclipse.cdt.qt.core.QMLTernCompletion;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.ui.IFileEditorInput;
public class QMLContentAssistProcessor implements IContentAssistProcessor {
private static final IContextInformation[] NO_CONTEXTS = {};
private static final ICompletionProposal[] NO_COMPLETIONS = {};
private final QMLAnalyzer analyzer = Activator.getService(QMLAnalyzer.class);
private final QMLEditor editor;
public QMLContentAssistProcessor(QMLEditor editor) {
this.editor = editor;
}
@Override
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
IDocument document = viewer.getDocument();
String prefix = lastWord(document, offset);
// Save the file
IFileEditorInput fileInput = (IFileEditorInput) editor.getEditorInput();
String fileName = fileInput.getFile().getName();// getLocation().toOSString().substring(1);
try {
String contents = document.get();
analyzer.addFile(fileName, contents);
Collection<QMLTernCompletion> completions = analyzer.getCompletions(fileName, offset);
if (!completions.isEmpty()) {
ICompletionProposal[] proposals = new ICompletionProposal[completions.size()];
int i = 0;
for (QMLTernCompletion completion : completions) {
String name = completion.getName();
String type = completion.getType();
String displayString = name;
if (type != null) {
displayString += " : " + completion.getType(); //$NON-NLS-1$
}
proposals[i++] = new CompletionProposal(name, offset - prefix.length(), prefix.length(),
name.length(), null, displayString, null, completion.getOrigin());
}
return proposals;
}
} catch (NoSuchMethodException | ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return NO_COMPLETIONS;
}
private String lastWord(IDocument document, int offset) {
try {
for (int n = offset - 1; n >= 0; n--) {
char c = document.getChar(n);
if (!Character.isJavaIdentifierPart(c)) {
return document.get(n + 1, offset - n - 1);
}
}
return document.get(0, offset);
} catch (BadLocationException e) {
Activator.log(e);
}
return ""; //$NON-NLS-1$
}
@Override
public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
return NO_CONTEXTS;
}
@Override
public char[] getCompletionProposalAutoActivationCharacters() {
return new char[] { '.' };
}
@Override
public char[] getContextInformationAutoActivationCharacters() {
// TODO not sure
return null;
}
@Override
public String getErrorMessage() {
// TODO Auto-generated method stub
return null;
}
@Override
public IContextInformationValidator getContextInformationValidator() {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -14,6 +14,9 @@ import org.eclipse.cdt.internal.qt.ui.editor.QMLEditor;
import org.eclipse.cdt.internal.qt.ui.editor.QMLKeywords;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
@ -44,14 +47,18 @@ public class QMLSourceViewerConfiguration extends TextSourceViewerConfiguration
// Just using Qt Creator defaults-ish for now
// TODO: Add preference page for syntax highlighting
private static final IToken[] allTokens = new IToken[] {
new Token(null),
private static final IToken[] allTokens = new IToken[] { new Token(null),
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 155, 200)))),
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 155, 200)))),
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(155, 155, 0)), null, SWT.BOLD)),
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 155, 0)), null, SWT.ITALIC)),
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 100, 155)), null, SWT.BOLD))
};
new Token(new TextAttribute(new Color(Display.getCurrent(), new RGB(0, 100, 155)), null, SWT.BOLD)) };
private final QMLEditor editor;
public QMLSourceViewerConfiguration(QMLEditor editor) {
this.editor = editor;
}
@Override
public IPresentationReconciler getPresentationReconciler(ISourceViewer viewer) {
@ -112,7 +119,8 @@ public class QMLSourceViewerConfiguration extends TextSourceViewerConfiguration
}
}, allTokens[TOKEN_DEFAULT]);
// Works decently well for now. However, some keywords like 'color' can also be used as identifiers. Can only fix this with
// Works decently well for now. However, some keywords like 'color' can
// also be used as identifiers. Can only fix this with
// semantic highlighting after the parser is completed.
for (String keyword : QMLKeywords.getKeywords(true)) {
wordRule.addWord(keyword, allTokens[TOKEN_KEYWORD]);
@ -142,4 +150,14 @@ public class QMLSourceViewerConfiguration extends TextSourceViewerConfiguration
return wordRule;
}
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
ContentAssistant contentAssistant = new ContentAssistant();
IContentAssistProcessor processor = new QMLContentAssistProcessor(editor);
contentAssistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
contentAssistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
return contentAssistant;
}
}

View file

@ -13,7 +13,7 @@ package org.eclipse.cdt.internal.qt.ui.text;
import java.util.ArrayList;
import java.util.Locale;
import org.eclipse.cdt.internal.qt.ui.QtUIPlugin;
import org.eclipse.cdt.internal.qt.ui.Activator;
import org.eclipse.cdt.internal.qt.ui.editor.QtProjectFileKeyword;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
@ -24,7 +24,7 @@ import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
public class ContentAssistProcessor implements IContentAssistProcessor {
public class QtProjectFileContentAssistProcessor implements IContentAssistProcessor {
private final IContextInformation[] NO_CONTEXTS = {};
private final ICompletionProposal[] NO_COMPLETIONS = {};
@ -38,28 +38,27 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
String prefix = lastWord(document, offset).toLowerCase(Locale.ROOT);
for (QtProjectFileKeyword keyword : QtProjectFileKeyword.values()) {
if (prefix.isEmpty() || keyword.getKeyword().toLowerCase(Locale.ROOT).startsWith(prefix)) {
result.add(new CompletionProposal(
keyword.getKeyword(),
offset - prefix.length(),
prefix.length(),
result.add(new CompletionProposal(keyword.getKeyword(), offset - prefix.length(), prefix.length(),
keyword.getKeyword().length()));
}
}
return result.toArray(new ICompletionProposal[result.size()]);
} catch (Exception e) {
QtUIPlugin.log(e);
Activator.log(e);
return NO_COMPLETIONS;
}
}
/**
* Returns the valid Java identifier in a document immediately before the given offset.
* Returns the valid Java identifier in a document immediately before the
* given offset.
*
* @param document
* the document
* @param offset
* the offset at which to start looking
* @return the Java identifier preceding this location or a blank string if none
* @return the Java identifier preceding this location or a blank string if
* none
*/
private String lastWord(IDocument document, int offset) {
try {
@ -71,7 +70,7 @@ public class ContentAssistProcessor implements IContentAssistProcessor {
}
return document.get(0, offset);
} catch (BadLocationException e) {
QtUIPlugin.log(e);
Activator.log(e);
}
return ""; //$NON-NLS-1$
}

View file

@ -95,7 +95,7 @@ public class QtProjectFileSourceViewerConfiguration extends TextSourceViewerConf
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
ContentAssistant contentAssistant = new ContentAssistant();
IContentAssistProcessor processor = new ContentAssistProcessor();
IContentAssistProcessor processor = new QtProjectFileContentAssistProcessor();
contentAssistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
contentAssistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
return contentAssistant;