mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 481126 - Walk QML Types AST
Added several classes that can be used to aggregate all of the information from within a .qmltypes file as defined by http://doc.qt.io/qt-5/qtqml-modules-qmldir.html#writing-a-qmltypes-file Change-Id: Ia36c3bb1a4a0254c4125733d6faabbb5a4606133 Signed-off-by: Matthew Bastien <mbastien@blackberry.com>
This commit is contained in:
parent
c68dc46f54
commit
0027b29aba
21 changed files with 1254 additions and 95 deletions
|
@ -615,7 +615,8 @@
|
||||||
throw new Error("QML only supports ECMA Script Language Specification 5 or older");
|
throw new Error("QML only supports ECMA Script Language Specification 5 or older");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.mode === "qml" || this.options.mode === "qmltypes") {
|
// Disabled 'qmltypes' mode for now since the normal parser can't parse it anyway
|
||||||
|
if (this.options.mode === "qml") {
|
||||||
// Force strict mode
|
// Force strict mode
|
||||||
this.strict = true;
|
this.strict = true;
|
||||||
|
|
||||||
|
|
|
@ -55,18 +55,6 @@ var stats, modes = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Normal QMLTypes": {
|
|
||||||
config: {
|
|
||||||
parse: acorn.parse,
|
|
||||||
options: {
|
|
||||||
mode: "qmltypes"
|
|
||||||
},
|
|
||||||
filter: function (test) {
|
|
||||||
var opts = test.options || {};
|
|
||||||
return opts.normal !== false && opts.qmltypes !== false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Loose QMLTypes": {
|
"Loose QMLTypes": {
|
||||||
config: {
|
config: {
|
||||||
parse: acorn.parse_dammit,
|
parse: acorn.parse_dammit,
|
||||||
|
|
|
@ -34,11 +34,14 @@ import org.eclipse.cdt.qt.core.qmljs.IQmlASTNode;
|
||||||
@SuppressWarnings("nls")
|
@SuppressWarnings("nls")
|
||||||
public class QMLAnalyzer implements IQMLAnalyzer {
|
public class QMLAnalyzer implements IQMLAnalyzer {
|
||||||
|
|
||||||
|
private QMLModuleResolver moduleResolver;
|
||||||
private ScriptEngine engine;
|
private ScriptEngine engine;
|
||||||
private Invocable invoke;
|
private Invocable invoke;
|
||||||
private Object tern;
|
private Object tern;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void load() throws ScriptException, IOException, NoSuchMethodException {
|
public void load() throws ScriptException, IOException, NoSuchMethodException {
|
||||||
|
moduleResolver = new QMLModuleResolver(this);
|
||||||
engine = new ScriptEngineManager().getEngineByName("nashorn");
|
engine = new ScriptEngineManager().getEngineByName("nashorn");
|
||||||
invoke = (Invocable) engine;
|
invoke = (Invocable) engine;
|
||||||
|
|
||||||
|
@ -88,6 +91,7 @@ public class QMLAnalyzer implements IQMLAnalyzer {
|
||||||
return fixPathString(path.normalize().toString());
|
return fixPathString(path.normalize().toString());
|
||||||
};
|
};
|
||||||
options.put("resolveDirectory", invoke.invokeFunction("resolveDirectory", resolveDirectory));
|
options.put("resolveDirectory", invoke.invokeFunction("resolveDirectory", resolveDirectory));
|
||||||
|
options.put("resolveModule", invoke.invokeFunction("resolveModule", moduleResolver));
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
tern = invoke.invokeFunction("newTernServer", options);
|
tern = invoke.invokeFunction("newTernServer", options);
|
||||||
|
@ -203,19 +207,13 @@ public class QMLAnalyzer implements IQMLAnalyzer {
|
||||||
public IQmlASTNode parseString(String text, String mode, boolean locations, boolean ranges)
|
public IQmlASTNode parseString(String text, String mode, boolean locations, boolean ranges)
|
||||||
throws NoSuchMethodException, ScriptException {
|
throws NoSuchMethodException, ScriptException {
|
||||||
waitUntilLoaded();
|
waitUntilLoaded();
|
||||||
Bindings query = engine.createBindings();
|
|
||||||
query.put("type", "parseString");
|
|
||||||
query.put("text", text);
|
|
||||||
Bindings options = engine.createBindings();
|
Bindings options = engine.createBindings();
|
||||||
options.put("mode", mode);
|
options.put("mode", mode);
|
||||||
options.put("locations", locations);
|
options.put("locations", locations);
|
||||||
options.put("ranges", ranges);
|
options.put("ranges", ranges);
|
||||||
query.put("options", options);
|
|
||||||
Bindings request = engine.createBindings();
|
|
||||||
request.put("query", query);
|
|
||||||
|
|
||||||
ASTCallback callback = new ASTCallback();
|
ASTCallback callback = new ASTCallback();
|
||||||
invoke.invokeMethod(tern, "request", request, invoke.invokeFunction("requestCallback", callback));
|
invoke.invokeMethod(tern, "parseString", text, options, invoke.invokeFunction("requestCallback", callback));
|
||||||
return callback.getAST();
|
return callback.getAST();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.qt.core.qmltypes.QMLModelBuilder;
|
||||||
|
import org.eclipse.cdt.internal.qt.core.qmltypes.QMLModuleInfo;
|
||||||
|
import org.eclipse.cdt.qt.core.IQtInstall;
|
||||||
|
import org.eclipse.cdt.qt.core.IQtInstallManager;
|
||||||
|
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryInfo;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlASTNode;
|
||||||
|
|
||||||
|
public class QMLModuleResolver {
|
||||||
|
private final QMLAnalyzer analyzer;
|
||||||
|
private final IQtInstallManager manager;
|
||||||
|
private final QMLModelBuilder builder;
|
||||||
|
|
||||||
|
public QMLModuleResolver(QMLAnalyzer analyzer) {
|
||||||
|
this.analyzer = analyzer;
|
||||||
|
this.manager = Activator.getService(IQtInstallManager.class);
|
||||||
|
this.builder = new QMLModelBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: determine exactly how to give this to Tern. For now we'll just return the reference to the QMLModuleInfo
|
||||||
|
// that we found
|
||||||
|
public QMLModuleInfo resolveModule(String module) throws NoSuchMethodException, ScriptException {
|
||||||
|
QMLModuleInfo info = builder.getModule(module);
|
||||||
|
if (info == null) {
|
||||||
|
Path path = getModulePath(module);
|
||||||
|
if (path != null) {
|
||||||
|
File qmldir = path.resolve("qmldir").normalize().toFile(); //$NON-NLS-1$
|
||||||
|
try {
|
||||||
|
String types = getQmlTypesFile(qmldir);
|
||||||
|
File qmlTypes = path.resolve(types).toFile();
|
||||||
|
String typeContents = fileToString(qmlTypes);
|
||||||
|
IQmlASTNode ast = analyzer.parseString(typeContents, "qmltypes", false, false); //$NON-NLS-1$
|
||||||
|
info = builder.addModule(module, ast);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Activator.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fileToString(File file) throws IOException {
|
||||||
|
try (InputStream stream = new FileInputStream(file)) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int read = -1;
|
||||||
|
while ((read = stream.read()) != -1) {
|
||||||
|
sb.append((char) read);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQmlTypesFile(File qmldir) throws IOException {
|
||||||
|
try (InputStream stream = new FileInputStream(qmldir)) {
|
||||||
|
QMLDirectoryInfo info = new QMLDirectoryInfo(stream);
|
||||||
|
return info.getTypesFileName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getModulePath(String module) {
|
||||||
|
if (module != null) {
|
||||||
|
for (IQtInstall install : manager.getInstalls()) {
|
||||||
|
Path qmlPath = install.getQmlPath();
|
||||||
|
Path modPath = null;
|
||||||
|
if (module.equals("QtQuick")) { //$NON-NLS-1$
|
||||||
|
modPath = qmlPath.resolve("QtQuick.2").normalize(); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
modPath = qmlPath;
|
||||||
|
for (String part : module.split("\\.")) { //$NON-NLS-1$
|
||||||
|
modPath = modPath.resolve(part).normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (modPath.toFile().exists()) {
|
||||||
|
return modPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -150,11 +150,20 @@ public class QmlASTNodeHandler implements InvocationHandler {
|
||||||
methodResults.put(mName, handleObject(node.get(pName), method.getReturnType()));
|
methodResults.put(mName, handleObject(node.get(pName), method.getReturnType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return methodResults.get(method.getName());
|
return methodResults.get(mName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object handleObject(Object value, Class<?> expectedType) throws Throwable {
|
private Object handleObject(Object value, Class<?> expectedType) throws Throwable {
|
||||||
if (expectedType.isAssignableFrom(ISourceLocation.class)) {
|
if (expectedType.isArray()) {
|
||||||
|
Object arr = Array.newInstance(expectedType.getComponentType(), ((Bindings) value).size());
|
||||||
|
int ctr = 0;
|
||||||
|
for (Object obj : ((Bindings) value).values()) {
|
||||||
|
Array.set(arr, ctr++, handleObject(obj, expectedType.getComponentType()));
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
} else if (expectedType.equals(Object.class)) {
|
||||||
|
return value;
|
||||||
|
} else if (expectedType.isAssignableFrom(ISourceLocation.class)) {
|
||||||
// ISourceLocation doesn't correspond to an AST Node and needs to be created manually from
|
// ISourceLocation doesn't correspond to an AST Node and needs to be created manually from
|
||||||
// the given Bindings.
|
// the given Bindings.
|
||||||
if (value instanceof Bindings) {
|
if (value instanceof Bindings) {
|
||||||
|
@ -170,13 +179,6 @@ public class QmlASTNodeHandler implements InvocationHandler {
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
return new SourceLocation();
|
return new SourceLocation();
|
||||||
} else if (expectedType.isArray()) {
|
|
||||||
Object arr = Array.newInstance(expectedType.getComponentType(), ((Bindings) value).size());
|
|
||||||
int ctr = 0;
|
|
||||||
for (Object obj : ((Bindings) value).values()) {
|
|
||||||
Array.set(arr, ctr++, handleObject(obj, expectedType.getComponentType()));
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
} else if (expectedType.isAssignableFrom(List.class)) {
|
} else if (expectedType.isAssignableFrom(List.class)) {
|
||||||
if (value instanceof Bindings) {
|
if (value instanceof Bindings) {
|
||||||
List<Object> list = new ArrayList<>();
|
List<Object> list = new ArrayList<>();
|
||||||
|
|
|
@ -40,6 +40,11 @@ public class QtInstall implements IQtInstall {
|
||||||
return qmakePath.resolve("../lib"); //$NON-NLS-1$
|
return qmakePath.resolve("../lib"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getQmlPath() {
|
||||||
|
return qmakePath.resolve("../../qml"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
public static String getSpec(String qmakePath) throws IOException {
|
public static String getSpec(String qmakePath) throws IOException {
|
||||||
Process proc = new ProcessBuilder(qmakePath, "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$
|
Process proc = new ProcessBuilder(qmakePath, "-query", "QMAKE_XSPEC").start(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
|
||||||
|
public class QMLComponentInfo {
|
||||||
|
static final String IDENTIFIER = "Component"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_PROTOTYPE = "prototype"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_DEF_PROPERTY = "defaultProperty"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_ATTACHED_TYPE = "attachedType"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_EXPORTS = "exports"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_EXPORT_REVISIONS = "exportMetaObjectRevisions"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String prototype;
|
||||||
|
private String defaultProperty;
|
||||||
|
private String attachedType;
|
||||||
|
private Integer[] exportMetaObjectRevisions;
|
||||||
|
private List<QMLExportInfo> exportList = new ArrayList<>();
|
||||||
|
private List<QMLPropertyInfo> propertyList = new ArrayList<>();
|
||||||
|
private List<QMLMethodInfo> methodList = new ArrayList<>();
|
||||||
|
private List<QMLSignalInfo> signalList = new ArrayList<>();
|
||||||
|
private List<QMLEnumInfo> enumList = new ArrayList<>();
|
||||||
|
|
||||||
|
protected QMLComponentInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER);
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (member instanceof IQmlPropertyBinding) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_PROTOTYPE:
|
||||||
|
this.prototype = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_DEF_PROPERTY:
|
||||||
|
this.defaultProperty = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_ATTACHED_TYPE:
|
||||||
|
this.attachedType = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_EXPORTS:
|
||||||
|
String[] exports = builder.getStringArrayBinding(prop);
|
||||||
|
for (String exp : exports) {
|
||||||
|
this.exportList.add(new QMLExportInfo(builder, exp));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROPERTY_EXPORT_REVISIONS:
|
||||||
|
this.exportMetaObjectRevisions = builder.getIntegerArrayBinding(prop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else if (member instanceof IQmlObjectDefinition) {
|
||||||
|
IQmlObjectDefinition object = (IQmlObjectDefinition) member;
|
||||||
|
switch (object.getIdentifier().getName()) {
|
||||||
|
case QMLPropertyInfo.IDENTIFIER:
|
||||||
|
this.propertyList.add(new QMLPropertyInfo(builder, object));
|
||||||
|
break;
|
||||||
|
case QMLMethodInfo.IDENTIFIER:
|
||||||
|
this.methodList.add(new QMLMethodInfo(builder, object));
|
||||||
|
break;
|
||||||
|
case QMLSignalInfo.IDENTIFIER:
|
||||||
|
this.signalList.add(new QMLSignalInfo(builder, object));
|
||||||
|
break;
|
||||||
|
case QMLEnumInfo.IDENTIFIER:
|
||||||
|
this.enumList.add(new QMLEnumInfo(builder, object));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.unexpectedNode(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exportList = Collections.unmodifiableList(exportList);
|
||||||
|
propertyList = Collections.unmodifiableList(propertyList);
|
||||||
|
methodList = Collections.unmodifiableList(methodList);
|
||||||
|
signalList = Collections.unmodifiableList(signalList);
|
||||||
|
enumList = Collections.unmodifiableList(enumList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrototype() {
|
||||||
|
return prototype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultProperty() {
|
||||||
|
return defaultProperty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttachedType() {
|
||||||
|
return attachedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLExportInfo> getExports() {
|
||||||
|
return exportList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] getExportMetaObjectRevisions() {
|
||||||
|
return Arrays.copyOf(exportMetaObjectRevisions, exportMetaObjectRevisions.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLPropertyInfo> getProperties() {
|
||||||
|
return propertyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLMethodInfo> getMethods() {
|
||||||
|
return methodList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLSignalInfo> getSignals() {
|
||||||
|
return signalList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLEnumInfo> getEnums() {
|
||||||
|
return enumList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IJSObjectExpression;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IJSProperty;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlScriptBinding;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.QMLExpressionEvaluator;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.QMLExpressionEvaluator.InvalidExpressionException;
|
||||||
|
|
||||||
|
public class QMLEnumInfo {
|
||||||
|
public static class EnumConst {
|
||||||
|
private final String identifier;
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private EnumConst(String ident, int val) {
|
||||||
|
this.identifier = ident;
|
||||||
|
this.value = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifier() {
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final String IDENTIFIER = "Enum"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_VALUE = "values"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private List<EnumConst> constantList = new ArrayList<>();
|
||||||
|
|
||||||
|
QMLEnumInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (builder.ensureNode(member, IQmlPropertyBinding.class)) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_VALUE:
|
||||||
|
if (builder.ensureNode(prop.getBinding(), IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding binding = ((IQmlScriptBinding) prop.getBinding());
|
||||||
|
if (builder.ensureNode(binding.getScript(), IJSObjectExpression.class)) {
|
||||||
|
IJSObjectExpression objExpr = (IJSObjectExpression) binding.getScript();
|
||||||
|
for (IJSProperty property : objExpr.getProperties()) {
|
||||||
|
Object value;
|
||||||
|
try {
|
||||||
|
value = QMLExpressionEvaluator.evaluateConstExpr(property.getValue());
|
||||||
|
if (value instanceof Number) {
|
||||||
|
constantList.add(new EnumConst(property.getType(), ((Number) value).intValue()));
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
builder.handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constantList = Collections.unmodifiableList(constantList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EnumConst> getConstants() {
|
||||||
|
return constantList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
public class QMLExportInfo {
|
||||||
|
private String type;
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
QMLExportInfo(QMLModelBuilder builder, String export) {
|
||||||
|
String[] info = export.split("\\h+"); //$NON-NLS-1$
|
||||||
|
switch (info.length) {
|
||||||
|
case 2:
|
||||||
|
this.type = info[0];
|
||||||
|
this.version = info[1];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this.type = info[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
|
||||||
|
public class QMLMethodInfo {
|
||||||
|
static final String IDENTIFIER = "Method"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ s
|
||||||
|
static final String PROPERTY_TYPE = "type"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_REVISION = "revision"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
private int revision;
|
||||||
|
private List<QMLParameterInfo> parameterList = new ArrayList<>();
|
||||||
|
|
||||||
|
QMLMethodInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (member instanceof IQmlPropertyBinding) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_TYPE:
|
||||||
|
this.type = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_REVISION:
|
||||||
|
this.revision = builder.getIntegerBinding(prop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else if (member instanceof IQmlObjectDefinition) {
|
||||||
|
this.parameterList.add(new QMLParameterInfo(builder, (IQmlObjectDefinition) member));
|
||||||
|
} else {
|
||||||
|
builder.unexpectedNode(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IJSArrayExpression;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IJSExpression;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlASTNode;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlBinding;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlProgram;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlQualifiedID;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlRootObject;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlScriptBinding;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.QMLExpressionEvaluator;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.QMLExpressionEvaluator.InvalidExpressionException;
|
||||||
|
|
||||||
|
public class QMLModelBuilder {
|
||||||
|
|
||||||
|
private final Map<String, QMLModuleInfo> moduleMap = new HashMap<>();
|
||||||
|
|
||||||
|
public QMLModelBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public QMLModuleInfo addModule(String module, IQmlASTNode ast) {
|
||||||
|
QMLModuleInfo info = moduleMap.get(module);
|
||||||
|
if (!moduleMap.containsKey(module)) {
|
||||||
|
if (ensureNode(ast, IQmlProgram.class)) {
|
||||||
|
IQmlRootObject obj = ((IQmlProgram) ast).getRootObject();
|
||||||
|
if (ensureNode(obj, IQmlRootObject.class)) {
|
||||||
|
info = new QMLModuleInfo(this, obj);
|
||||||
|
moduleMap.put(module, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QMLModuleInfo getModule(String module) {
|
||||||
|
return moduleMap.get(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasModule(String module) {
|
||||||
|
return moduleMap.get(module) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ensureIdentifier(IQmlQualifiedID actual, String expected) {
|
||||||
|
if (!actual.getName().equals(expected)) {
|
||||||
|
Activator.log("[QmlTypes] Unexpected node identifier: expected '" + expected + "', but was '" //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
+ actual.getName() + "'"); //$NON-NLS-1$
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ensureNode(IQmlASTNode actual, Class<? extends IQmlASTNode> expected) {
|
||||||
|
if (!expected.isInstance(actual)) {
|
||||||
|
Activator.log("[QmlTypes] Expected node '" + expected + "', but was '" + actual.getClass().getInterfaces()[0] + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ensureValue(Object actual, Class<?> expected) {
|
||||||
|
if (!expected.isInstance(actual)) {
|
||||||
|
Activator.log("[QmlTypes] Unexpected value: expected '" + expected + "', but was '" //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
+ actual.getClass().getInterfaces()[0] + "'"); //$NON-NLS-1$
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unexpectedNode(IQmlASTNode node) {
|
||||||
|
Activator.log("[QmlTypes] Unexpected node '" + node.getClass().getInterfaces()[0] + "'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
String getStringBinding(IQmlPropertyBinding prop) {
|
||||||
|
IQmlBinding b = prop.getBinding();
|
||||||
|
if (ensureNode(b, IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding sb = (IQmlScriptBinding) b;
|
||||||
|
if (ensureNode(sb.getScript(), IJSExpression.class)) {
|
||||||
|
try {
|
||||||
|
Object value = QMLExpressionEvaluator.evaluateConstExpr((IJSExpression) sb.getScript());
|
||||||
|
if (value instanceof String) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] getStringArrayBinding(IQmlPropertyBinding prop) {
|
||||||
|
ArrayList<String> result = new ArrayList<>();
|
||||||
|
IQmlBinding b = prop.getBinding();
|
||||||
|
if (ensureNode(b, IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding sb = (IQmlScriptBinding) b;
|
||||||
|
if (ensureNode(sb.getScript(), IJSArrayExpression.class)) {
|
||||||
|
IJSArrayExpression arrExpr = (IJSArrayExpression) sb.getScript();
|
||||||
|
for (IJSExpression expr : arrExpr.getElements()) {
|
||||||
|
try {
|
||||||
|
Object value = QMLExpressionEvaluator.evaluateConstExpr(expr);
|
||||||
|
if (value instanceof String) {
|
||||||
|
result.add((String) value);
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new String[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] getIntegerArrayBinding(IQmlPropertyBinding prop) {
|
||||||
|
ArrayList<Integer> result = new ArrayList<>();
|
||||||
|
IQmlBinding b = prop.getBinding();
|
||||||
|
if (ensureNode(b, IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding sb = (IQmlScriptBinding) b;
|
||||||
|
if (ensureNode(sb.getScript(), IJSArrayExpression.class)) {
|
||||||
|
IJSArrayExpression arrExpr = (IJSArrayExpression) sb.getScript();
|
||||||
|
for (IJSExpression expr : arrExpr.getElements()) {
|
||||||
|
try {
|
||||||
|
Object value = QMLExpressionEvaluator.evaluateConstExpr(expr);
|
||||||
|
if (value instanceof Number) {
|
||||||
|
result.add(((Number) value).intValue());
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new Integer[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean getBooleanBinding(IQmlPropertyBinding prop) {
|
||||||
|
IQmlBinding b = prop.getBinding();
|
||||||
|
if (ensureNode(b, IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding sb = (IQmlScriptBinding) b;
|
||||||
|
if (ensureNode(sb.getScript(), IJSExpression.class)) {
|
||||||
|
try {
|
||||||
|
Object value = QMLExpressionEvaluator.evaluateConstExpr((IJSExpression) sb.getScript());
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return (Boolean) value;
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getIntegerBinding(IQmlPropertyBinding prop) {
|
||||||
|
IQmlBinding b = prop.getBinding();
|
||||||
|
if (ensureNode(b, IQmlScriptBinding.class)) {
|
||||||
|
IQmlScriptBinding sb = (IQmlScriptBinding) b;
|
||||||
|
if (ensureNode(sb.getScript(), IJSExpression.class)) {
|
||||||
|
try {
|
||||||
|
Object value = QMLExpressionEvaluator.evaluateConstExpr((IJSExpression) sb.getScript());
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
} catch (InvalidExpressionException e) {
|
||||||
|
handleException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleException(Throwable t) {
|
||||||
|
Activator.log("[QmlTypes] " + t.getMessage()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlRootObject;
|
||||||
|
|
||||||
|
public class QMLModuleInfo {
|
||||||
|
static final String IDENTIFIER = "Module"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private List<QMLComponentInfo> componentsList = new ArrayList<>();
|
||||||
|
|
||||||
|
QMLModuleInfo(QMLModelBuilder builder, IQmlRootObject obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (builder.ensureNode(member, IQmlObjectDefinition.class)) {
|
||||||
|
componentsList.add(new QMLComponentInfo(builder, (IQmlObjectDefinition) member));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
componentsList = Collections.unmodifiableList(componentsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<QMLComponentInfo> getComponents() {
|
||||||
|
return componentsList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
|
||||||
|
public class QMLParameterInfo {
|
||||||
|
static final String IDENTIFIER = "Parameter"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_TYPE = "type"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
QMLParameterInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (builder.ensureNode(member, IQmlPropertyBinding.class)) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_TYPE:
|
||||||
|
this.type = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
|
||||||
|
public class QMLPropertyInfo {
|
||||||
|
static final String IDENTIFIER = "Property"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_TYPE = "type"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_READONLY = "isReadonly"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_POINTER = "isPointer"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_LIST = "isList"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_REVISION = "revision"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
private boolean readonly = false;
|
||||||
|
private boolean pointer = false;
|
||||||
|
private boolean list = false;
|
||||||
|
private int revision;
|
||||||
|
|
||||||
|
QMLPropertyInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (builder.ensureNode(member, IQmlPropertyBinding.class)) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_TYPE:
|
||||||
|
this.type = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_READONLY:
|
||||||
|
this.readonly = builder.getBooleanBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_POINTER:
|
||||||
|
this.pointer = builder.getBooleanBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_LIST:
|
||||||
|
this.list = builder.getBooleanBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_REVISION:
|
||||||
|
this.revision = builder.getIntegerBinding(prop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return readonly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPointer() {
|
||||||
|
return pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.qt.core.qmltypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectDefinition;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlObjectMember;
|
||||||
|
import org.eclipse.cdt.qt.core.qmljs.IQmlPropertyBinding;
|
||||||
|
|
||||||
|
public class QMLSignalInfo {
|
||||||
|
static final String IDENTIFIER = "Signal"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
static final String PROPERTY_NAME = "name"; //$NON-NLS-1$ s
|
||||||
|
static final String PROPERTY_TYPE = "type"; //$NON-NLS-1$
|
||||||
|
static final String PROPERTY_REVISION = "revision"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String type;
|
||||||
|
private Integer revision;
|
||||||
|
private List<QMLParameterInfo> parameterList = new ArrayList<>();
|
||||||
|
|
||||||
|
QMLSignalInfo(QMLModelBuilder builder, IQmlObjectDefinition obj) {
|
||||||
|
if (builder.ensureIdentifier(obj.getIdentifier(), IDENTIFIER)) {
|
||||||
|
for (IQmlObjectMember member : obj.getBody().getMembers()) {
|
||||||
|
if (member instanceof IQmlPropertyBinding) {
|
||||||
|
IQmlPropertyBinding prop = (IQmlPropertyBinding) member;
|
||||||
|
switch (prop.getIdentifier().getName()) {
|
||||||
|
case PROPERTY_NAME:
|
||||||
|
this.name = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_TYPE:
|
||||||
|
this.type = builder.getStringBinding(prop);
|
||||||
|
break;
|
||||||
|
case PROPERTY_REVISION:
|
||||||
|
this.revision = builder.getIntegerBinding(prop);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else if (member instanceof IQmlObjectDefinition) {
|
||||||
|
this.parameterList.add(new QMLParameterInfo(builder, (IQmlObjectDefinition) member));
|
||||||
|
} else {
|
||||||
|
builder.unexpectedNode(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,4 +25,6 @@ public interface IQtInstall {
|
||||||
|
|
||||||
Path getLibPath();
|
Path getLibPath();
|
||||||
|
|
||||||
|
Path getQmlPath();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.qt.core.qmldir;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||||
|
|
||||||
|
public class QMLDirectoryInfo {
|
||||||
|
public static class Module {
|
||||||
|
private final String name;
|
||||||
|
private final String initialVersion;
|
||||||
|
|
||||||
|
public Module(String name, String ver) {
|
||||||
|
this.name = name;
|
||||||
|
this.initialVersion = ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInitialVersion() {
|
||||||
|
return initialVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Plugin {
|
||||||
|
private final String name;
|
||||||
|
private final Path path;
|
||||||
|
|
||||||
|
private Plugin(String name, String path) {
|
||||||
|
this.name = name;
|
||||||
|
Path p = null;
|
||||||
|
if (path != null) {
|
||||||
|
try {
|
||||||
|
p = Paths.get(path);
|
||||||
|
} catch (InvalidPathException e) {
|
||||||
|
Activator.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.path = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getRelativePath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResourceFile {
|
||||||
|
private final String name;
|
||||||
|
private final boolean internal;
|
||||||
|
private final boolean singleton;
|
||||||
|
private final String initialVersion;
|
||||||
|
|
||||||
|
private ResourceFile(String name, String ver, boolean internal, boolean singleton) {
|
||||||
|
this.name = name;
|
||||||
|
this.initialVersion = ver;
|
||||||
|
this.internal = internal;
|
||||||
|
this.singleton = singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInitialVersion() {
|
||||||
|
return initialVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSingleton() {
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInternal() {
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String moduleIdentifier;
|
||||||
|
private Plugin plugin;
|
||||||
|
private String classname;
|
||||||
|
private String typeInfo;
|
||||||
|
private final Collection<Module> depends;
|
||||||
|
private final Collection<ResourceFile> resources;
|
||||||
|
private boolean designersupported;
|
||||||
|
|
||||||
|
public QMLDirectoryInfo(InputStream input) {
|
||||||
|
this.depends = new LinkedList<>();
|
||||||
|
this.resources = new LinkedList<>();
|
||||||
|
|
||||||
|
IQDirAST ast = new QMLDirectoryParser().parse(input);
|
||||||
|
for (IQDirCommand c : ast.getCommands()) {
|
||||||
|
if (c instanceof IQDirModuleCommand) {
|
||||||
|
if (moduleIdentifier == null) {
|
||||||
|
moduleIdentifier = ((IQDirModuleCommand) c).getModuleIdentifier().getText();
|
||||||
|
}
|
||||||
|
} else if (c instanceof IQDirPluginCommand) {
|
||||||
|
if (plugin == null) {
|
||||||
|
IQDirPluginCommand pc = (IQDirPluginCommand) c;
|
||||||
|
plugin = new Plugin(pc.getName().getText(), pc.getPath() != null ? pc.getPath().getText() : null);
|
||||||
|
}
|
||||||
|
} else if (c instanceof IQDirTypeInfoCommand) {
|
||||||
|
if (typeInfo == null) {
|
||||||
|
typeInfo = ((IQDirTypeInfoCommand) c).getFile().getText();
|
||||||
|
}
|
||||||
|
} else if (c instanceof IQDirResourceCommand) {
|
||||||
|
IQDirResourceCommand rc = (IQDirResourceCommand) c;
|
||||||
|
resources.add(new ResourceFile(rc.getFile().getText(),
|
||||||
|
rc.getInitialVersion().getVersionString(),
|
||||||
|
false, false));
|
||||||
|
} else if (c instanceof IQDirInternalCommand) {
|
||||||
|
IQDirInternalCommand rc = (IQDirInternalCommand) c;
|
||||||
|
resources.add(new ResourceFile(rc.getFile().getText(),
|
||||||
|
null, true, false));
|
||||||
|
} else if (c instanceof IQDirSingletonCommand) {
|
||||||
|
IQDirSingletonCommand rc = (IQDirSingletonCommand) c;
|
||||||
|
resources.add(new ResourceFile(rc.getFile().getText(),
|
||||||
|
rc.getInitialVersion().getVersionString(),
|
||||||
|
false, true));
|
||||||
|
} else if (c instanceof IQDirDependsCommand) {
|
||||||
|
IQDirDependsCommand dc = (IQDirDependsCommand) c;
|
||||||
|
depends.add(new Module(dc.getModuleIdentifier().getText(),
|
||||||
|
dc.getInitialVersion().getVersionString()));
|
||||||
|
} else if (c instanceof IQDirClassnameCommand) {
|
||||||
|
if (classname == null) {
|
||||||
|
classname = ((IQDirClassnameCommand) c).getIdentifier().getText();
|
||||||
|
}
|
||||||
|
} else if (c instanceof IQDirDesignerSupportedCommand) {
|
||||||
|
designersupported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModuleIdentifier() {
|
||||||
|
return moduleIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassname() {
|
||||||
|
return classname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypesFileName() {
|
||||||
|
return typeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Module> getDependentModules() {
|
||||||
|
return Collections.unmodifiableCollection(depends);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<ResourceFile> getResources() {
|
||||||
|
return Collections.unmodifiableCollection(resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDesignersupported() {
|
||||||
|
return designersupported;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.qt.core.qmljs;
|
||||||
|
|
||||||
|
public final class QMLExpressionEvaluator {
|
||||||
|
private QMLExpressionEvaluator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidExpressionException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4803923632666457229L;
|
||||||
|
|
||||||
|
private IJSExpression offendingExpression;
|
||||||
|
|
||||||
|
public InvalidExpressionException(String msg, IJSExpression expr) {
|
||||||
|
super(msg);
|
||||||
|
this.offendingExpression = expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IJSExpression getOffendingExpression() {
|
||||||
|
return offendingExpression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates the given {@link IJSExpression} as a constant expression and returns the result. At the moment this only supports
|
||||||
|
* very simple expressions involving unary operators and literals alone. Support for more complex expressions will be added as
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @param expr
|
||||||
|
* the expression to be evaluated
|
||||||
|
*
|
||||||
|
* @throws InvalidExpressionException
|
||||||
|
* if the given expression can't be reduced to a single constant
|
||||||
|
*/
|
||||||
|
public static Object evaluateConstExpr(IJSExpression expr) throws InvalidExpressionException {
|
||||||
|
if (expr instanceof IJSLiteral) {
|
||||||
|
return ((IJSLiteral) expr).getValue();
|
||||||
|
} else if (expr instanceof IJSUnaryExpression) {
|
||||||
|
IJSUnaryExpression unary = (IJSUnaryExpression) expr;
|
||||||
|
Object arg = evaluateConstExpr(unary.getArgument());
|
||||||
|
switch (unary.getOperator()) {
|
||||||
|
case Plus:
|
||||||
|
return unaryPlus(arg, unary.getArgument());
|
||||||
|
case Negation:
|
||||||
|
return unaryNegate(arg, unary.getArgument());
|
||||||
|
case BitwiseNot:
|
||||||
|
return unaryBitwiseNot(arg, unary.getArgument());
|
||||||
|
case Not:
|
||||||
|
return unaryNot(arg, unary.getArgument());
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new InvalidExpressionException("Cannot reduce '" + expr + "' to a constant", expr); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object unaryPlus(Object object, IJSExpression expr) throws InvalidExpressionException {
|
||||||
|
if (object instanceof Byte) {
|
||||||
|
return +((Byte) object);
|
||||||
|
} else if (object instanceof Short) {
|
||||||
|
return +((Short) object);
|
||||||
|
} else if (object instanceof Integer) {
|
||||||
|
return +((Integer) object);
|
||||||
|
} else if (object instanceof Long) {
|
||||||
|
return +((Long) object);
|
||||||
|
} else if (object instanceof Float) {
|
||||||
|
return +((Float) object);
|
||||||
|
} else if (object instanceof Double) {
|
||||||
|
return +((Double) object);
|
||||||
|
}
|
||||||
|
throw new InvalidExpressionException("Cannot perform unary plus operation on a non-number", expr); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object unaryNegate(Object object, IJSExpression expr) throws InvalidExpressionException {
|
||||||
|
if (object instanceof Byte) {
|
||||||
|
return -((Byte) object);
|
||||||
|
} else if (object instanceof Short) {
|
||||||
|
return -((Short) object);
|
||||||
|
} else if (object instanceof Integer) {
|
||||||
|
return -((Integer) object);
|
||||||
|
} else if (object instanceof Long) {
|
||||||
|
return -((Long) object);
|
||||||
|
} else if (object instanceof Float) {
|
||||||
|
return -((Float) object);
|
||||||
|
} else if (object instanceof Double) {
|
||||||
|
return -((Double) object);
|
||||||
|
}
|
||||||
|
throw new InvalidExpressionException("Cannot perform unary negation operation on a non-number", expr); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object unaryBitwiseNot(Object object, IJSExpression expr) throws InvalidExpressionException {
|
||||||
|
if (object instanceof Byte) {
|
||||||
|
return ~((Byte) object);
|
||||||
|
} else if (object instanceof Short) {
|
||||||
|
return ~((Short) object);
|
||||||
|
} else if (object instanceof Integer) {
|
||||||
|
return ~((Integer) object);
|
||||||
|
} else if (object instanceof Long) {
|
||||||
|
return ~((Long) object);
|
||||||
|
} else if (object instanceof Float || object instanceof Double) {
|
||||||
|
return ~((Number) object).longValue();
|
||||||
|
}
|
||||||
|
throw new InvalidExpressionException("Cannot perform binary not operation on a non-number", expr); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object unaryNot(Object object, IJSExpression expr) throws InvalidExpressionException {
|
||||||
|
if (object instanceof Boolean) {
|
||||||
|
return !((Boolean) object);
|
||||||
|
}
|
||||||
|
throw new InvalidExpressionException("Cannot perform unary not operation on a non-boolean", expr); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,12 @@ function resolveDirectory(obj) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveModule(obj) {
|
||||||
|
return function (module) {
|
||||||
|
return obj.resolveModule(module);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function requestCallback(obj) {
|
function requestCallback(obj) {
|
||||||
return function (err, data) {
|
return function (err, data) {
|
||||||
obj.callback(err, data);
|
obj.callback(err, data);
|
||||||
|
|
|
@ -65,6 +65,12 @@
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
},
|
},
|
||||||
|
resolveModule: function (module) {
|
||||||
|
var impl = this.server.options.resolveModule;
|
||||||
|
if (impl) {
|
||||||
|
return impl(module);
|
||||||
|
}
|
||||||
|
},
|
||||||
updateDirectoryImportList: function () {
|
updateDirectoryImportList: function () {
|
||||||
if (!this.imports) {
|
if (!this.imports) {
|
||||||
this.imports = {};
|
this.imports = {};
|
||||||
|
@ -961,35 +967,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Called when a parse query is made to the server.
|
|
||||||
*/
|
|
||||||
function parse(srv, query, file) {
|
|
||||||
var ast = null;
|
|
||||||
if (query.file) {
|
|
||||||
// Get the file's AST. It should have been parsed already by the server.
|
|
||||||
ast = file.ast;
|
|
||||||
} else {
|
|
||||||
// Parse the file manually and get the AST.
|
|
||||||
var options = {
|
|
||||||
directSourceFile: file,
|
|
||||||
allowReturnOutsideFunction: true,
|
|
||||||
allowImportExportEverywhere: true,
|
|
||||||
ecmaVersion: srv.options.ecmaVersion
|
|
||||||
};
|
|
||||||
for (var opt in query.options) {
|
|
||||||
options[opt] = query.options[opt];
|
|
||||||
}
|
|
||||||
query.text = query.text || "";
|
|
||||||
var text = srv.signalReturnFirst("preParse", query.text, options) || query.text;
|
|
||||||
ast = infer.parse(text, options);
|
|
||||||
srv.signal("postParse", ast, text);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
ast: ast
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register the QML plugin in Tern
|
// Register the QML plugin in Tern
|
||||||
tern.registerPlugin("qml", function (server) {
|
tern.registerPlugin("qml", function (server) {
|
||||||
// First we want to replace the top-level defs array with our own and save the
|
// First we want to replace the top-level defs array with our own and save the
|
||||||
|
@ -1003,19 +980,41 @@
|
||||||
if (this.cx) this.reset();
|
if (this.cx) this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Create a method on the server object that parses a string. We can't make this
|
||||||
|
// a query due to the fact that tern always does its infer processing on every
|
||||||
|
// query regardless of its contents.
|
||||||
|
server.parseString = function (text, options, callback) {
|
||||||
|
try {
|
||||||
|
var opts = {
|
||||||
|
allowReturnOutsideFunction: true,
|
||||||
|
allowImportExportEverywhere: true,
|
||||||
|
ecmaVersion: this.options.ecmaVersion
|
||||||
|
};
|
||||||
|
for (var opt in options) {
|
||||||
|
opts[opt] = options[opt];
|
||||||
|
}
|
||||||
|
text = this.signalReturnFirst("preParse", text, opts) || text;
|
||||||
|
var ast = infer.parse(text, opts);
|
||||||
|
callback(null, {
|
||||||
|
ast: ast
|
||||||
|
});
|
||||||
|
this.signal("postParse", ast, text);
|
||||||
|
} catch (err) {
|
||||||
|
callback(err, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Create the QML Import Handler
|
// Create the QML Import Handler
|
||||||
qmlImportHandler = exports.importHandler = new ImportHandler(server);
|
qmlImportHandler = exports.importHandler = new ImportHandler(server);
|
||||||
|
|
||||||
// Define the 'parseFile' and 'parseString' query types. The reason we need
|
// Define the 'parseFile' query type.
|
||||||
// two separate queries for these is that Tern will not allow us to resolve
|
|
||||||
// a file without 'takesFile' being true. However, if we set 'takesFile' to
|
|
||||||
// true, Tern will not allow a null file in the query.
|
|
||||||
tern.defineQueryType("parseFile", {
|
tern.defineQueryType("parseFile", {
|
||||||
takesFile: true,
|
takesFile: true,
|
||||||
run: parse
|
run: function (srv, query, file) {
|
||||||
});
|
return {
|
||||||
tern.defineQueryType("parseString", {
|
ast: file.ast
|
||||||
run: parse
|
};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hook into server signals
|
// Hook into server signals
|
||||||
|
|
|
@ -61,12 +61,7 @@ test("{Parse given file}", function (server, callback, name) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("{Parse empty text}", function (server, callback, name) {
|
test("{Parse empty text}", function (server, callback, name) {
|
||||||
server.request({
|
server.parseString("", null, function (err, resp) {
|
||||||
query: {
|
|
||||||
type: "parseString",
|
|
||||||
text: ""
|
|
||||||
}
|
|
||||||
}, function (err, resp) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -80,12 +75,7 @@ test("{Parse empty text}", function (server, callback, name) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("{Parse text no mode}", function (server, callback, name) {
|
test("{Parse text no mode}", function (server, callback, name) {
|
||||||
server.request({
|
server.parseString("import QtQuick 2.0\nModule {\n\tComponent {\n\t}\n}", null, function (err, resp) {
|
||||||
query: {
|
|
||||||
type: "parseString",
|
|
||||||
text: "import QtQuick 2.0\nModule {\n\tComponent {\n\t}\n}"
|
|
||||||
}
|
|
||||||
}, function (err, resp) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
@ -99,14 +89,8 @@ test("{Parse text no mode}", function (server, callback, name) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("{Parse text (mode: qmltypes)}", function (server, callback, name) {
|
test("{Parse text (mode: qmltypes)}", function (server, callback, name) {
|
||||||
server.request({
|
server.parseString("QtObject {\n\tobj: {\n\t\tprop1: 1,\n\t\tprop2: 2\n\t}\n}", {
|
||||||
query: {
|
mode: "qmltypes"
|
||||||
type: "parseString",
|
|
||||||
text: "QtObject {\n\tobj: {\n\t\tprop1: 1,\n\t\tprop2: 2\n\t}\n}",
|
|
||||||
options: {
|
|
||||||
mode: "qmltypes"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, function (err, resp) {
|
}, function (err, resp) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -121,15 +105,9 @@ test("{Parse text (mode: qmltypes)}", function (server, callback, name) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("{Parse text with locations}", function (server, callback, name) {
|
test("{Parse text with locations}", function (server, callback, name) {
|
||||||
server.request({
|
server.parseString("var w = 3", {
|
||||||
query: {
|
mode: "js",
|
||||||
type: "parseString",
|
locations: true
|
||||||
text: "var w = 3",
|
|
||||||
options: {
|
|
||||||
mode: "js",
|
|
||||||
locations: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, function (err, resp) {
|
}, function (err, resp) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw err;
|
throw err;
|
||||||
|
|
Loading…
Add table
Reference in a new issue