/******************************************************************************* * 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; } }