mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-19 15:05:36 +02:00
Bug 481126 - QML Directory File Parsing
Added a new parser that is able to construct an AST for a given qmldir file. Added tests to ensure the parser works for standard qmldir files. Change-Id: I292aace3cdec8b4a544033f80812df965fef50b8 Signed-off-by: Matthew Bastien <mbastien@blackberry.com>
This commit is contained in:
parent
c5d03dddb6
commit
1d36f36ef8
40 changed files with 2434 additions and 1 deletions
|
@ -0,0 +1,287 @@
|
|||
/*******************************************************************************
|
||||
* 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.tests;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.location.Position;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.Token;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.TokenType;
|
||||
import org.junit.Test;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
public class QMLDirectoryLexerTests {
|
||||
private void assertToken(TokenType type, String text, int start, int end, Position locStart, Position locEnd, Token actual) {
|
||||
// Check token type and text
|
||||
assertEquals("Unexpected token type", type, actual.getType());
|
||||
assertEquals("Unexpected token text", text, actual.getText());
|
||||
|
||||
// Check position offsets
|
||||
assertEquals("Unexpected start position", start, actual.getStart());
|
||||
assertEquals("Unexpected end position", end, actual.getEnd());
|
||||
|
||||
// Check SourceLocation start
|
||||
assertEquals("Unexpected location start line", locStart.getLine(), actual.getLocation().getStart().getLine());
|
||||
assertEquals("Unexpected location start column", locStart.getColumn(), actual.getLocation().getStart().getColumn());
|
||||
|
||||
// Check SourceLocation end
|
||||
assertEquals("Unexpected location end line", locEnd.getLine(), actual.getLocation().getEnd().getLine());
|
||||
assertEquals("Unexpected location end column", locEnd.getColumn(), actual.getLocation().getEnd().getColumn());
|
||||
}
|
||||
|
||||
private InputStream createInputStream(String s) {
|
||||
return new ByteArrayInputStream(s.getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(new ByteArrayInputStream("# This is a comment".getBytes()));
|
||||
assertToken(TokenType.COMMENT,
|
||||
"# This is a comment",
|
||||
0, 19,
|
||||
new Position(1, 0), new Position(1, 19),
|
||||
lexer.nextToken(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleCommentTokens() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("# This is a comment\n# This is another comment\n"));
|
||||
assertToken(TokenType.COMMENT,
|
||||
"# This is a comment",
|
||||
0, 19,
|
||||
new Position(1, 0), new Position(1, 19),
|
||||
lexer.nextToken(false));
|
||||
assertEquals(TokenType.COMMAND_END, lexer.nextToken(false).getType());
|
||||
assertToken(TokenType.COMMENT,
|
||||
"# This is another comment",
|
||||
20, 45,
|
||||
new Position(2, 0), new Position(2, 25),
|
||||
lexer.nextToken(false));
|
||||
assertEquals(TokenType.COMMAND_END, lexer.nextToken(false).getType());
|
||||
assertEquals(TokenType.EOF, lexer.nextToken(false).getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("module"));
|
||||
assertToken(TokenType.MODULE,
|
||||
"module",
|
||||
0, 6,
|
||||
new Position(1, 0), new Position(1, 6),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeInfoToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("typeinfo"));
|
||||
assertToken(TokenType.TYPEINFO,
|
||||
"typeinfo",
|
||||
0, 8,
|
||||
new Position(1, 0), new Position(1, 8),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("singleton"));
|
||||
assertToken(TokenType.SINGLETON,
|
||||
"singleton",
|
||||
0, 9,
|
||||
new Position(1, 0), new Position(1, 9),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInternalToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("internal"));
|
||||
assertToken(TokenType.INTERNAL,
|
||||
"internal",
|
||||
0, 8,
|
||||
new Position(1, 0), new Position(1, 8),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPluginToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("plugin"));
|
||||
assertToken(TokenType.PLUGIN,
|
||||
"plugin",
|
||||
0, 6,
|
||||
new Position(1, 0), new Position(1, 6),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassnameToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("classname"));
|
||||
assertToken(TokenType.CLASSNAME,
|
||||
"classname",
|
||||
0, 9,
|
||||
new Position(1, 0), new Position(1, 9),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependsToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("depends"));
|
||||
assertToken(TokenType.DEPENDS,
|
||||
"depends",
|
||||
0, 7,
|
||||
new Position(1, 0), new Position(1, 7),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDesignerSupportedToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("designersupported"));
|
||||
assertToken(TokenType.DESIGNERSUPPORTED,
|
||||
"designersupported",
|
||||
0, 17,
|
||||
new Position(1, 0), new Position(1, 17),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("QtQuick.Control"));
|
||||
assertToken(TokenType.WORD,
|
||||
"QtQuick.Control",
|
||||
0, 15,
|
||||
new Position(1, 0), new Position(1, 15),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordTokenContainsKeyword() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("plugins.test"));
|
||||
assertToken(TokenType.WORD,
|
||||
"plugins.test",
|
||||
0, 12,
|
||||
new Position(1, 0), new Position(1, 12),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordTokenAsRelativePath() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("./test/something/"));
|
||||
assertToken(TokenType.WORD,
|
||||
"./test/something/",
|
||||
0, 17,
|
||||
new Position(1, 0), new Position(1, 17),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordTokenAsAbsoluteWindowsPath() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("C:\\Users\\someone\\test\\something\\"));
|
||||
assertToken(TokenType.WORD,
|
||||
"C:\\Users\\someone\\test\\something\\",
|
||||
0, 32,
|
||||
new Position(1, 0), new Position(1, 32),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWordTokenAsAbsoluteUnixPath() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("/usr/local/test/something/"));
|
||||
assertToken(TokenType.WORD,
|
||||
"/usr/local/test/something/",
|
||||
0, 26,
|
||||
new Position(1, 0), new Position(1, 26),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecimalToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("2.3"));
|
||||
assertToken(TokenType.DECIMAL,
|
||||
"2.3",
|
||||
0, 3,
|
||||
new Position(1, 0), new Position(1, 3),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("3"));
|
||||
assertToken(TokenType.INTEGER,
|
||||
"3",
|
||||
0, 1,
|
||||
new Position(1, 0), new Position(1, 1),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWhitespaceToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream(" \t\n"));
|
||||
assertToken(TokenType.WHITESPACE,
|
||||
" \t",
|
||||
0, 2,
|
||||
new Position(1, 0), new Position(1, 2),
|
||||
lexer.nextToken(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommandEndToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("\n"));
|
||||
assertToken(TokenType.COMMAND_END,
|
||||
"\\n",
|
||||
0, 1,
|
||||
new Position(1, 0), new Position(1, 1),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEOFToken() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream(""));
|
||||
assertToken(TokenType.EOF,
|
||||
"",
|
||||
0, 0,
|
||||
new Position(1, 0), new Position(1, 0),
|
||||
lexer.nextToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEOFTokenAfterCommand() {
|
||||
QMLDirectoryLexer lexer = new QMLDirectoryLexer();
|
||||
lexer.setInput(createInputStream("\n"));
|
||||
lexer.nextToken();
|
||||
assertToken(TokenType.EOF,
|
||||
"",
|
||||
1, 1,
|
||||
new Position(2, 0), new Position(2, 0),
|
||||
lexer.nextToken());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
/*******************************************************************************
|
||||
* 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.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.location.Position;
|
||||
import org.eclipse.cdt.qt.core.location.IPosition;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirAST;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirASTNode;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirClassnameCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirCommentCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirDependsCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirDesignerSupportedCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirInternalCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirModuleCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirPluginCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirResourceCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirSingletonCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirSyntaxError;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirTypeInfoCommand;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryParser;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryParser.SyntaxError;
|
||||
import org.junit.Test;
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
public class QMLDirectoryParserTests {
|
||||
|
||||
public void assertLocation(int start, int end, IPosition locStart, IPosition locEnd, IQDirASTNode node) {
|
||||
// Check position offsets
|
||||
assertEquals("Unexpected start position", start, node.getStart());
|
||||
assertEquals("Unexpected end position", end, node.getEnd());
|
||||
|
||||
// Check SourceLocation start
|
||||
assertEquals("Unexpected location start line", locStart.getLine(), node.getLocation().getStart().getLine());
|
||||
assertEquals("Unexpected location start column", locStart.getColumn(), node.getLocation().getStart().getColumn());
|
||||
}
|
||||
|
||||
private InputStream createInputStream(String s) {
|
||||
return new ByteArrayInputStream(s.getBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("module QtQuick.Controls\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirModuleCommand.class));
|
||||
IQDirModuleCommand mod = (IQDirModuleCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected qualified ID", "QtQuick.Controls", mod.getModuleIdentifier().getText());
|
||||
assertLocation(0, 24, new Position(1, 0), new Position(1, 24), mod);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModuleNoIdentifier() {
|
||||
try {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
parser.parse(createInputStream("module\n"), false);
|
||||
fail("Parser did not throw SyntaxError");
|
||||
} catch (SyntaxError e) {
|
||||
assertEquals("Unexpected token '\\n' (1:6)", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingletonCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("singleton Singleton 2.3 Singleton.qml\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirSingletonCommand.class));
|
||||
IQDirSingletonCommand singleton = (IQDirSingletonCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected type name", "Singleton", singleton.getTypeName().getText());
|
||||
assertEquals("Unexpected initial version", "2.3", singleton.getInitialVersion().getVersionString());
|
||||
assertEquals("Unexpected file name", "Singleton.qml", singleton.getFile().getText());
|
||||
assertLocation(0, 38, new Position(1, 0), new Position(1, 38), singleton);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidVersionNumber() {
|
||||
try {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
parser.parse(createInputStream("singleton Singleton 2 Singleton.qml\n"), false);
|
||||
fail("Parser did not throw SyntaxError");
|
||||
} catch (SyntaxError e) {
|
||||
assertEquals("Unexpected token '2' (1:20)", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInternalCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("internal MyPrivateType MyPrivateType.qml\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirInternalCommand.class));
|
||||
IQDirInternalCommand internal = (IQDirInternalCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected type name", "MyPrivateType", internal.getTypeName().getText());
|
||||
assertEquals("Unexpected file name", "MyPrivateType.qml", internal.getFile().getText());
|
||||
assertLocation(0, 41, new Position(1, 0), new Position(1, 41), internal);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("MyScript 1.0 MyScript.qml\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirResourceCommand.class));
|
||||
IQDirResourceCommand resource = (IQDirResourceCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected type name", "MyScript", resource.getResourceIdentifier().getText());
|
||||
assertEquals("Unexpected initial version", "1.0", resource.getInitialVersion().getVersionString());
|
||||
assertEquals("Unexpected file name", "MyScript.qml", resource.getFile().getText());
|
||||
assertLocation(0, 26, new Position(1, 0), new Position(1, 26), resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPluginCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("plugin MyPluginLibrary\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirPluginCommand.class));
|
||||
IQDirPluginCommand plugin = (IQDirPluginCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected identifier", "MyPluginLibrary", plugin.getName().getText());
|
||||
assertEquals("Unexpected path", null, plugin.getPath());
|
||||
assertLocation(0, 23, new Position(1, 0), new Position(1, 23), plugin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPluginCommandWithPath() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("plugin MyPluginLibrary ./lib/\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirPluginCommand.class));
|
||||
IQDirPluginCommand plugin = (IQDirPluginCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected identifier", "MyPluginLibrary", plugin.getName().getText());
|
||||
assertEquals("Unexpected path", "./lib/", plugin.getPath().getText());
|
||||
assertLocation(0, 30, new Position(1, 0), new Position(1, 30), plugin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClassnameCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("classname MyClass\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirClassnameCommand.class));
|
||||
IQDirClassnameCommand classname = (IQDirClassnameCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected class name", "MyClass", classname.getIdentifier().getText());
|
||||
assertLocation(0, 18, new Position(1, 0), new Position(1, 18), classname);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTypeInfoCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("typeinfo mymodule.qmltypes\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirTypeInfoCommand.class));
|
||||
IQDirTypeInfoCommand typeinfo = (IQDirTypeInfoCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected file name", "mymodule.qmltypes", typeinfo.getFile().getText());
|
||||
assertLocation(0, 27, new Position(1, 0), new Position(1, 27), typeinfo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDependsCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("depends MyOtherModule 1.0\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirDependsCommand.class));
|
||||
IQDirDependsCommand depends = (IQDirDependsCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected module identifier", "MyOtherModule", depends.getModuleIdentifier().getText());
|
||||
assertEquals("Unexpected initial version", "1.0", depends.getInitialVersion().getVersionString());
|
||||
assertLocation(0, 26, new Position(1, 0), new Position(1, 26), depends);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDesignerSupportedCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("designersupported\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirDesignerSupportedCommand.class));
|
||||
assertLocation(0, 18, new Position(1, 0), new Position(1, 18), ast.getCommands().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCommentCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("# This is a comment command\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirCommentCommand.class));
|
||||
IQDirCommentCommand comment = (IQDirCommentCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected text", "# This is a comment command", comment.getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyntaxErrorCommand() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("classname"));
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirSyntaxError.class));
|
||||
IQDirSyntaxError err = (IQDirSyntaxError) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected message", "Unexpected token 'EOF' (1:9)", err.getSyntaxError().getMessage());
|
||||
assertLocation(0, 9, new Position(1, 0), new Position(1, 9), err);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSyntaxErrorCommandIncludesWholeLine() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("classname class extra\n"));
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirSyntaxError.class));
|
||||
IQDirSyntaxError err = (IQDirSyntaxError) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected message", "Expected token '\\n' or 'EOF', but saw 'extra' (1:16)",
|
||||
err.getSyntaxError().getMessage());
|
||||
assertLocation(0, 22, new Position(1, 0), new Position(1, 22), err);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExampleQMLDirFile() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("module QtQuick\n" +
|
||||
"plugin qtquick2plugin\n" +
|
||||
"classname QtQuick2Plugin\n" +
|
||||
"typeinfo plugins.qmltypes\n" +
|
||||
"designersupported\n"));
|
||||
|
||||
assertEquals("Unexpected command list size", 5, ast.getCommands().size());
|
||||
// Module Command (index 0)
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirModuleCommand.class));
|
||||
IQDirModuleCommand mod = (IQDirModuleCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected module qualified ID", "QtQuick", mod.getModuleIdentifier().getText());
|
||||
// Plugin Command (index 1)
|
||||
assertThat("Unexpected command", ast.getCommands().get(1), instanceOf(IQDirPluginCommand.class));
|
||||
IQDirPluginCommand plugin = (IQDirPluginCommand) ast.getCommands().get(1);
|
||||
assertEquals("Unexpected plugin identifier", "qtquick2plugin", plugin.getName().getText());
|
||||
assertEquals("Unexpected plugin path", null, plugin.getPath());
|
||||
// Classname Command (index 2)
|
||||
assertThat("Unexpected command", ast.getCommands().get(2), instanceOf(IQDirClassnameCommand.class));
|
||||
IQDirClassnameCommand classname = (IQDirClassnameCommand) ast.getCommands().get(2);
|
||||
assertEquals("Unexpected class name", "QtQuick2Plugin", classname.getIdentifier().getText());
|
||||
// Type Info Command (index 3)
|
||||
assertThat("Unexpected command", ast.getCommands().get(3), instanceOf(IQDirTypeInfoCommand.class));
|
||||
IQDirTypeInfoCommand typeinfo = (IQDirTypeInfoCommand) ast.getCommands().get(3);
|
||||
assertEquals("Unexpected type info file name", "plugins.qmltypes", typeinfo.getFile().getText());
|
||||
// Designer Supported Command (index 4)
|
||||
assertThat("Unexpected command", ast.getCommands().get(4), instanceOf(IQDirDesignerSupportedCommand.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExampleQMLDirFileWithError() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
IQDirAST ast = parser.parse(createInputStream("module QtQuick\n" +
|
||||
"plugin qtquick2plugin\n" +
|
||||
"classnames QtQuick2Plugin\n" +
|
||||
"typeinfo plugins.qmltypes\n" +
|
||||
"designersupported\n"));
|
||||
|
||||
assertEquals("Unexpected command list size", 5, ast.getCommands().size());
|
||||
// Module Command (index 0)
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirModuleCommand.class));
|
||||
IQDirModuleCommand mod = (IQDirModuleCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected module qualified ID", "QtQuick", mod.getModuleIdentifier().getText());
|
||||
// Plugin Command (index 1)
|
||||
assertThat("Unexpected command", ast.getCommands().get(1), instanceOf(IQDirPluginCommand.class));
|
||||
IQDirPluginCommand plugin = (IQDirPluginCommand) ast.getCommands().get(1);
|
||||
assertEquals("Unexpected plugin identifier", "qtquick2plugin", plugin.getName().getText());
|
||||
assertEquals("Unexpected plugin path", null, plugin.getPath());
|
||||
// Syntax Error Command (index 2)
|
||||
assertThat("Unexpected command", ast.getCommands().get(2), instanceOf(IQDirSyntaxError.class));
|
||||
IQDirSyntaxError err = (IQDirSyntaxError) ast.getCommands().get(2);
|
||||
assertEquals("Unexpected error message", "Unexpected token 'QtQuick2Plugin' (3:11)", err.getSyntaxError().getMessage());
|
||||
// Type Info Command (index 3)
|
||||
assertThat("Unexpected command", ast.getCommands().get(3), instanceOf(IQDirTypeInfoCommand.class));
|
||||
IQDirTypeInfoCommand typeinfo = (IQDirTypeInfoCommand) ast.getCommands().get(3);
|
||||
assertEquals("Unexpected type info file name", "plugins.qmltypes", typeinfo.getFile().getText());
|
||||
// Designer Supported Command (index 4)
|
||||
assertThat("Unexpected command", ast.getCommands().get(4), instanceOf(IQDirDesignerSupportedCommand.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseTwoDifferentStreams() {
|
||||
QMLDirectoryParser parser = new QMLDirectoryParser();
|
||||
|
||||
// Parse module QtQuick.Controls
|
||||
IQDirAST ast = parser.parse(createInputStream("module QtQuick.Controls\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirModuleCommand.class));
|
||||
IQDirModuleCommand mod = (IQDirModuleCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected qualified ID", "QtQuick.Controls", mod.getModuleIdentifier().getText());
|
||||
assertLocation(0, 24, new Position(1, 0), new Position(1, 24), mod);
|
||||
|
||||
// Parse a second module MyModule
|
||||
ast = parser.parse(createInputStream("module MyModule\n"), false);
|
||||
assertEquals("Unexpected command list size", 1, ast.getCommands().size());
|
||||
assertThat("Unexpected command", ast.getCommands().get(0), instanceOf(IQDirModuleCommand.class));
|
||||
mod = (IQDirModuleCommand) ast.getCommands().get(0);
|
||||
assertEquals("Unexpected qualified ID", "MyModule", mod.getModuleIdentifier().getText());
|
||||
assertLocation(0, 16, new Position(1, 0), new Position(1, 16), mod);
|
||||
}
|
||||
}
|
|
@ -25,6 +25,10 @@ Bundle-Localization: plugin
|
|||
Export-Package: org.eclipse.cdt.internal.qt.core;x-friends:="org.eclipse.cdt.qt.ui,org.eclipse.cdt.qt.ui.tests",
|
||||
org.eclipse.cdt.internal.qt.core.build;x-friends:="org.eclipse.cdt.qt.ui",
|
||||
org.eclipse.cdt.internal.qt.core.index;x-friends:="org.eclipse.cdt.qt.ui.tests",
|
||||
org.eclipse.cdt.internal.qt.core.location;x-friends:="org.eclipse.cdt.qt.core.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.qt.core
|
||||
org.eclipse.cdt.internal.qt.core.qmldir;x-friends:="org.eclipse.cdt.qt.core.tests",
|
||||
org.eclipse.cdt.qt.core;x-friends:="org.eclipse.cdt.qt.core.tests",
|
||||
org.eclipse.cdt.qt.core.location,
|
||||
org.eclipse.cdt.qt.core.qmldir
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* 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.location;
|
||||
|
||||
import org.eclipse.cdt.qt.core.location.IPosition;
|
||||
|
||||
public class Position implements IPosition {
|
||||
private final int line;
|
||||
private final int column;
|
||||
|
||||
public Position(int line, int column) {
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + line + ":" + column + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* 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.location;
|
||||
|
||||
import org.eclipse.cdt.qt.core.location.IPosition;
|
||||
import org.eclipse.cdt.qt.core.location.ISourceLocation;
|
||||
|
||||
public class SourceLocation implements ISourceLocation {
|
||||
private String source;
|
||||
private IPosition start;
|
||||
private IPosition end;
|
||||
|
||||
public SourceLocation() {
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
public SourceLocation(String source, IPosition start, IPosition end) {
|
||||
this.source = source;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public void setSource(String value) {
|
||||
this.source = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setStart(IPosition value) {
|
||||
this.start = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPosition getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setEnd(IPosition value) {
|
||||
this.end = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPosition getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirAST;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirCommand;
|
||||
|
||||
public class QDirAST extends QDirASTNode implements IQDirAST {
|
||||
private final List<IQDirCommand> commands;
|
||||
|
||||
public QDirAST() {
|
||||
commands = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addCommand(IQDirCommand command) {
|
||||
commands.add(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IQDirCommand> getCommands() {
|
||||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.location.SourceLocation;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirASTNode;
|
||||
|
||||
public class QDirASTNode implements IQDirASTNode {
|
||||
|
||||
private SourceLocation location;
|
||||
private int start;
|
||||
private int end;
|
||||
|
||||
public QDirASTNode() {
|
||||
this.location = new SourceLocation();
|
||||
this.start = -1;
|
||||
this.end = -1;
|
||||
}
|
||||
|
||||
public void setLocation(SourceLocation value) {
|
||||
this.location = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setStart(int value) {
|
||||
this.start = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setEnd(int value) {
|
||||
this.end = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirClassnameCommand;
|
||||
|
||||
public class QDirClassnameCommand extends QDirASTNode implements IQDirClassnameCommand {
|
||||
|
||||
private QDirWord ident;
|
||||
|
||||
public void setIdentifier(QDirWord value) {
|
||||
this.ident = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getIdentifier() {
|
||||
return ident;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirCommentCommand;
|
||||
|
||||
public class QDirCommentCommand extends QDirASTNode implements IQDirCommentCommand {
|
||||
|
||||
private String text;
|
||||
|
||||
public void setText(String value) {
|
||||
this.text = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirDependsCommand;
|
||||
|
||||
public class QDirDependsCommand extends QDirASTNode implements IQDirDependsCommand {
|
||||
|
||||
private QDirWord moduleName;
|
||||
private QDirVersion version;
|
||||
|
||||
public void setModuleIdentifier(QDirWord value) {
|
||||
this.moduleName = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getModuleIdentifier() {
|
||||
return moduleName;
|
||||
}
|
||||
|
||||
public void setInitialVersion(QDirVersion value) {
|
||||
this.version = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirVersion getInitialVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirDesignerSupportedCommand;
|
||||
|
||||
public class QDirDesignerSupportedCommand extends QDirASTNode implements IQDirDesignerSupportedCommand {
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirInternalCommand;
|
||||
|
||||
public class QDirInternalCommand extends QDirASTNode implements IQDirInternalCommand {
|
||||
|
||||
private QDirWord typeName;
|
||||
private QDirWord file;
|
||||
|
||||
public void setTypeName(QDirWord value) {
|
||||
this.typeName = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public void setFile(QDirWord value) {
|
||||
this.file = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirModuleCommand;
|
||||
|
||||
public class QDirModuleCommand extends QDirASTNode implements IQDirModuleCommand {
|
||||
private QDirWord identifier;
|
||||
|
||||
public void setModuleIdentifier(QDirWord value) {
|
||||
this.identifier = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getModuleIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirPluginCommand;
|
||||
|
||||
public class QDirPluginCommand extends QDirASTNode implements IQDirPluginCommand {
|
||||
|
||||
private QDirWord qid;
|
||||
private QDirWord path;
|
||||
|
||||
public void setName(QDirWord value) {
|
||||
this.qid = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getName() {
|
||||
return qid;
|
||||
}
|
||||
|
||||
public void setPath(QDirWord value) {
|
||||
this.path = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirResourceCommand;
|
||||
|
||||
public class QDirResourceCommand extends QDirASTNode implements IQDirResourceCommand {
|
||||
private QDirWord typeName;
|
||||
private QDirVersion version;
|
||||
private QDirWord file;
|
||||
|
||||
public void setResourceIdentifier(QDirWord value) {
|
||||
this.typeName = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getResourceIdentifier() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public void setInitialVersion(QDirVersion value) {
|
||||
this.version = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirVersion getInitialVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setFile(QDirWord value) {
|
||||
this.file = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirSingletonCommand;
|
||||
|
||||
public class QDirSingletonCommand extends QDirASTNode implements IQDirSingletonCommand {
|
||||
|
||||
private QDirWord typeName;
|
||||
private QDirVersion version;
|
||||
private QDirWord file;
|
||||
|
||||
public void setTypeName(QDirWord value) {
|
||||
this.typeName = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getTypeName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public void setInitialVersion(QDirVersion value) {
|
||||
this.version = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirVersion getInitialVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setFile(QDirWord value) {
|
||||
this.file = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
|
@ -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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirASTNode;
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirSyntaxError;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.Token;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryParser.SyntaxError;
|
||||
|
||||
public class QDirSyntaxError extends QDirASTNode implements IQDirSyntaxError {
|
||||
private SyntaxError exception;
|
||||
|
||||
public QDirSyntaxError(SyntaxError exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token getOffendingToken() {
|
||||
return this.exception.getOffendingToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQDirASTNode getIncompleteNode() {
|
||||
return this.exception.getIncompleteNode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyntaxError getSyntaxError() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirTypeInfoCommand;
|
||||
|
||||
public class QDirTypeInfoCommand extends QDirASTNode implements IQDirTypeInfoCommand {
|
||||
|
||||
private QDirWord file;
|
||||
|
||||
public void setFile(QDirWord value) {
|
||||
this.file = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QDirWord getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirVersion;
|
||||
|
||||
public class QDirVersion extends QDirASTNode implements IQDirVersion {
|
||||
|
||||
private String version;
|
||||
|
||||
public void setVersionString(String value) {
|
||||
this.version = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersionString() {
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* 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.qmldir;
|
||||
|
||||
import org.eclipse.cdt.qt.core.qmldir.IQDirWord;
|
||||
|
||||
public class QDirWord extends QDirASTNode implements IQDirWord {
|
||||
|
||||
private String text;
|
||||
|
||||
public void setText(String value) {
|
||||
this.text = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* 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.location;
|
||||
|
||||
/**
|
||||
* Stores a line/offset pair as integers.
|
||||
*/
|
||||
public interface IPosition {
|
||||
/**
|
||||
* Gets the one-indexed line number indicated by this <code>IPosition</code>
|
||||
*
|
||||
* @return the line number
|
||||
*/
|
||||
public int getLine();
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed column indicated by this <code>IPosition</code>
|
||||
*
|
||||
* @return the column
|
||||
*/
|
||||
public int getColumn();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*******************************************************************************
|
||||
* 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.location;
|
||||
|
||||
/**
|
||||
* Represents a location in a source file. Uses the {@link IPosition} interface to store the start and end locations as a
|
||||
* line/offset pair.
|
||||
*/
|
||||
public interface ISourceLocation {
|
||||
/**
|
||||
* Gets the String representing the source of this <code>ISourceLocation</code>
|
||||
*
|
||||
* @return the source or <code>null</code> if not available
|
||||
*/
|
||||
public String getSource();
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the start of this <code>ISourceLocation</code>
|
||||
*
|
||||
* @return the start offset
|
||||
*/
|
||||
public IPosition getStart();
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the end of this <code>ISourceLocation</code>
|
||||
*
|
||||
* @return the end offset
|
||||
*/
|
||||
public IPosition getEnd();
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* 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.util.List;
|
||||
|
||||
/**
|
||||
* The main entry point into the qmldir AST. This interface contains a list of Commands specified within the qmldir file that it
|
||||
* represents.
|
||||
*/
|
||||
public interface IQDirAST extends IQDirASTNode {
|
||||
/**
|
||||
* Gets the list of commands in the qmldir file that this <code>IQDirAST</code> represents.
|
||||
*
|
||||
* @return the list of all commands in the qmldir file
|
||||
*/
|
||||
public List<IQDirCommand> getCommands();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*******************************************************************************
|
||||
* 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 org.eclipse.cdt.qt.core.location.ISourceLocation;
|
||||
|
||||
/**
|
||||
* The base type for all qmldir AST nodes. Contains methods for retrieving a node's positional information.
|
||||
*/
|
||||
public interface IQDirASTNode {
|
||||
/**
|
||||
* Gets a more detailed description of this node's location than {@link IQDirASTNode#getStart()} and
|
||||
* {@link IQDirASTNode#getStart()}. This method allows the retrieval of line and column information in order to make output for
|
||||
* syntax errors and the like more human-readable.
|
||||
*
|
||||
* @return the {@link ISourceLocation} representing this node's location in the source
|
||||
*/
|
||||
public ISourceLocation getLocation();
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the start of this node in the source.
|
||||
*
|
||||
* @return the node's start offset
|
||||
*/
|
||||
public int getStart();
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the end of this node in the source.
|
||||
*
|
||||
* @return the node's end offset
|
||||
*/
|
||||
public int getEnd();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Classname Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirClassnameCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the identifier for the classname.
|
||||
*
|
||||
* @return the identifier for the classname
|
||||
*/
|
||||
public IQDirWord getIdentifier();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* The base interface for all qmldir AST nodes that function as commands.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirCommand extends IQDirASTNode {
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Comment Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirCommentCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the String representation of this comment as it appears in the qmldir file.
|
||||
*
|
||||
* @return the String representation of this comment
|
||||
*/
|
||||
public String getText();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Depends Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirDependsCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the module identifier that this qmldir module depends on.
|
||||
*
|
||||
* @return the module identifier
|
||||
*/
|
||||
public IQDirWord getModuleIdentifier();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirVersion</code> representing the initial version of the module that this qmldir module depends on.
|
||||
*
|
||||
* @return the initial version
|
||||
*/
|
||||
public IQDirVersion getInitialVersion();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Designer Supported Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirDesignerSupportedCommand extends IQDirCommand {
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing an Internal Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirInternalCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the type name of the internal type.
|
||||
*
|
||||
* @return the type names
|
||||
*/
|
||||
public IQDirWord getTypeName();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the filename of the internal type.
|
||||
*
|
||||
* @return the filename
|
||||
*/
|
||||
public IQDirWord getFile();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Module Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirModuleCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the identifier for the module.
|
||||
*
|
||||
* @return the identifier for the module
|
||||
*/
|
||||
public IQDirWord getModuleIdentifier();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Plugin Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirPluginCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the name of the plugin.
|
||||
*
|
||||
* @return the plugin name
|
||||
*/
|
||||
public IQDirWord getName();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the path to the plugin if it was given.
|
||||
*
|
||||
* @return the path to the plugin or <code>null</code> if not available
|
||||
*/
|
||||
public IQDirWord getPath();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Resource Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirResourceCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the identifier of the resource.
|
||||
*
|
||||
* @return the identifier of the resource
|
||||
*/
|
||||
public IQDirWord getResourceIdentifier();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirVersion</code> representing the initial version of the resource.
|
||||
*
|
||||
* @return the initial version
|
||||
*/
|
||||
public IQDirVersion getInitialVersion();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the filename of the resource.
|
||||
*
|
||||
* @return the filename
|
||||
*/
|
||||
public IQDirWord getFile();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Singleton Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirSingletonCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the type name of the singleton type.
|
||||
*
|
||||
* @return the type name
|
||||
*/
|
||||
public IQDirWord getTypeName();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirVersion</code> representing the initial version of the singleton type.
|
||||
*
|
||||
* @return the initial version
|
||||
*/
|
||||
public IQDirVersion getInitialVersion();
|
||||
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the filename of the singleton type.
|
||||
*
|
||||
* @return the filename
|
||||
*/
|
||||
public IQDirWord getFile();
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* 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 org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.Token;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryParser.SyntaxError;
|
||||
|
||||
/**
|
||||
* An AST Node representing a syntax error in a qmldir file. Due to the fact that the qmldir file is so simple, a syntax error will
|
||||
* only occur at the command level while the parser jumps to the next line to recover.
|
||||
*/
|
||||
public interface IQDirSyntaxError extends IQDirCommand {
|
||||
/**
|
||||
* Gets the token that caused the parser to fail. This is a helper method equivalent to
|
||||
* <code>getSyntaxError.getOffendingToken()</code>.
|
||||
*
|
||||
* @return the offending token.
|
||||
*/
|
||||
public Token getOffendingToken();
|
||||
|
||||
/**
|
||||
* Gets the node that the parser was working on before it failed (if available). This is a helper method equivalent to
|
||||
* <code>getSyntaxError.getIncompleteNode()</code>.
|
||||
*
|
||||
* @return the incomplete node or <code>null</code> if not available
|
||||
*/
|
||||
public IQDirASTNode getIncompleteNode();
|
||||
|
||||
/**
|
||||
* Gets the syntax error that occurred.
|
||||
*
|
||||
* @return the syntax error
|
||||
*/
|
||||
public SyntaxError getSyntaxError();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a Type Info Command in a qmldir file.
|
||||
*
|
||||
* @see <a href="http://doc.qt.io/qt-5/qtqml-modules-qmldir.html">Module Definition qmldir Files</a>
|
||||
*/
|
||||
public interface IQDirTypeInfoCommand extends IQDirCommand {
|
||||
/**
|
||||
* Gets the <code>IQDirWord</code> representing the filename of the type info file.
|
||||
*
|
||||
* @return the filename of the type info file
|
||||
*/
|
||||
public IQDirWord getFile();
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a version String of the form <MajorVersion>.<MinorVersion>
|
||||
*/
|
||||
public interface IQDirVersion extends IQDirASTNode {
|
||||
/**
|
||||
* Gets the String value of this version. The result will always be of the form "<MajorVersion>.<MinorVersion>"
|
||||
*
|
||||
* @return a string value of this version
|
||||
*/
|
||||
public String getVersionString();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* An AST Node representing a set of characters that does not contain whitespace and does not start with a digit. This encompasses
|
||||
* the syntax for Identifiers, Qualified IDs, Paths, and File Names all in one parser rule.
|
||||
*/
|
||||
public interface IQDirWord extends IQDirASTNode {
|
||||
/**
|
||||
* Gets the String representing this word as it appears in the qmldir file.<br>
|
||||
* <br>
|
||||
* <b>Note:</b> The text is not modified or validated in any way when it is parsed. It is necessary for the caller to perform
|
||||
* semantic validation of the returned value to ensure it represents a valid identifier, filename, or path.
|
||||
*
|
||||
* @return a string representing this word
|
||||
*/
|
||||
public String getText();
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/*******************************************************************************
|
||||
* 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.util.Scanner;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.location.Position;
|
||||
import org.eclipse.cdt.internal.qt.core.location.SourceLocation;
|
||||
import org.eclipse.cdt.qt.core.location.ISourceLocation;
|
||||
|
||||
/**
|
||||
* Converts an <code>InputStream</code> representing a qmldir file into a stream of tokens through successive calls to
|
||||
* <code>nextToken</code>. This lexer uses regular expressions to match its 16 valid token types:
|
||||
* <ul>
|
||||
* <li><b>COMMENT</b>: A single line comment that begins with '#'
|
||||
* <li><b>MODULE</b>: Keyword 'module'
|
||||
* <li><b>TYPEINFO</b>: The keyword 'typeinfo'
|
||||
* <li><b>SINGLETON</b>: The keyword 'singleton'
|
||||
* <li><b>INTERNAL</b>: The keyword 'internal'
|
||||
* <li><b>PLUGIN</b>: The keyword 'plugin'
|
||||
* <li><b>CLASSNAME</b>: The keyword 'classname'
|
||||
* <li><b>DEPENDS</b>: The keyword 'depends'
|
||||
* <li><b>DESIGNERSUPPORTED</b>: The keyword 'designersupported'
|
||||
* <li><b>WORD</b>: A group of characters that form an identifier, filename, or path
|
||||
* <li><b>DECIMAL</b>: A number of the form [0-9]+ '.' [0-9]+
|
||||
* <li><b>INTEGER</b>: An integer of the form [0-9]+
|
||||
* <li><b>WHITESPACE</b>: A group of whitespace characters (not including newlines)
|
||||
* <li><b>COMMAND_END</b>: A newline character
|
||||
* <li><b>UNKNOWN</b>: A group of characters that does not match any of the preceding tokens
|
||||
* <li><b>EOF</b>: End of File
|
||||
* </ul>
|
||||
*/
|
||||
public class QMLDirectoryLexer {
|
||||
/**
|
||||
* A single matched token returned by a <code>QMLDirectoryLexer</code>. A <code>Token</code> stores information on how it was
|
||||
* matched including the type of token, the exact text that was matched, and its position in the <code>InputStream</code> .
|
||||
*/
|
||||
public static class Token {
|
||||
private final TokenType tokType;
|
||||
private final String raw;
|
||||
private final ISourceLocation location;
|
||||
private final int start;
|
||||
private final int end;
|
||||
|
||||
private Token(TokenType type, MatchResult match, int line, int lineStart) {
|
||||
this(type, match.group(), match.start(), match.end(), line, lineStart);
|
||||
}
|
||||
|
||||
private Token(TokenType type, String raw, int start, int end, int line, int lineStart) {
|
||||
this.tokType = type;
|
||||
raw = raw.replaceAll("\n", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
raw = raw.replaceAll("\r", "\\\\r"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
this.raw = raw;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.location = new SourceLocation(null,
|
||||
new Position(line, start - lineStart),
|
||||
new Position(line, end - lineStart));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of token that was matched.
|
||||
*
|
||||
* @return the type of token
|
||||
*/
|
||||
public TokenType getType() {
|
||||
return tokType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw text that this token was matched with.
|
||||
*
|
||||
* @return a String representing the matched text
|
||||
*/
|
||||
public String getText() {
|
||||
return raw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a more detailed description of this token's location in the <code>InputStream</code> than {@link Token#getStart()}
|
||||
* and {@link Token#getEnd()}. This method allows the retrieval of line and column information in order to make output for
|
||||
* syntax errors and the like more human-readable.
|
||||
*
|
||||
* @return the {@link ISourceLocation} representing this token's location in the <code>InputStream</code>
|
||||
*/
|
||||
public ISourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the start of this token in the <code>InputStream</code>.
|
||||
*
|
||||
* @return the token's start offset
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the zero-indexed offset indicating the end of this token in the <code>InputStream</code>.
|
||||
*
|
||||
* @return the token's end offset
|
||||
*/
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An Enumeration encompassing the 16 possible types of tokens returned by a <code>QMLDirectoryLexer</code>.
|
||||
*
|
||||
* @see org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer
|
||||
*/
|
||||
public static enum TokenType {
|
||||
COMMENT("#.*$"), //$NON-NLS-1$
|
||||
MODULE("module(?=\\s|$)"), //$NON-NLS-1$
|
||||
TYPEINFO("typeinfo(?=\\s|$)"), //$NON-NLS-1$
|
||||
SINGLETON("singleton(?=\\s|$)"), //$NON-NLS-1$
|
||||
INTERNAL("internal(?=\\s|$)"), //$NON-NLS-1$
|
||||
PLUGIN("plugin(?=\\s|$)"), //$NON-NLS-1$
|
||||
CLASSNAME("classname(?=\\s|$)"), //$NON-NLS-1$
|
||||
DEPENDS("depends(?=\\s|$)"), //$NON-NLS-1$
|
||||
DESIGNERSUPPORTED("designersupported(?=\\s|$)"), //$NON-NLS-1$
|
||||
WORD("[^0-9\\s][^\\s]*"), //$NON-NLS-1$
|
||||
DECIMAL("[0-9]+\\.[0-9]+"), //$NON-NLS-1$
|
||||
INTEGER("[0-9]+"), //$NON-NLS-1$
|
||||
WHITESPACE("\\h+"), //$NON-NLS-1$
|
||||
COMMAND_END("(?:\r\n)|\n"), //$NON-NLS-1$
|
||||
UNKNOWN(".+"), //$NON-NLS-1$
|
||||
EOF(null);
|
||||
|
||||
private static Pattern pattern;
|
||||
|
||||
private static Pattern patternForAllTerminals() {
|
||||
if (pattern == null) {
|
||||
String regex = ""; //$NON-NLS-1$
|
||||
TokenType[] tokens = TokenType.values();
|
||||
for (int i = 0; i < TokenType.values().length; i++) {
|
||||
TokenType tok = tokens[i];
|
||||
if (tok.regex != null) {
|
||||
if (i != 0) {
|
||||
regex += "|"; //$NON-NLS-1$
|
||||
}
|
||||
regex += "(" + tok.regex + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
pattern = Pattern.compile(regex, Pattern.MULTILINE);
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
||||
private final String regex;
|
||||
|
||||
private TokenType(String regex) {
|
||||
this.regex = regex;
|
||||
}
|
||||
}
|
||||
|
||||
private Scanner input;
|
||||
private MatchResult lastMatch;
|
||||
private int currentLine;
|
||||
private int currentLineStart;
|
||||
|
||||
/**
|
||||
* Creates a new <code>QMLDirectoryLexer</code> without initializing any of the its internal state. A call to
|
||||
* <code>setInput</code> is necessary to fully initialize the lexer before any calls to <code>nextToken</code>.
|
||||
*/
|
||||
public QMLDirectoryLexer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for lexical analysis by giving the lexer an <code>InputStream</code> to retrieve text from.
|
||||
*
|
||||
* @param input
|
||||
* the input to perform lexical analysis on
|
||||
*/
|
||||
public void setInput(InputStream input) {
|
||||
this.input = new Scanner(input);
|
||||
this.lastMatch = null;
|
||||
this.currentLine = 1;
|
||||
this.currentLineStart = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next valid token from the <code>InputStream</code> given by <code>setInput</code>. This is a helper method to
|
||||
* skip whitespace that is equivalent to <code>QMLDirectoryLexer.nextToken(true)</code>.
|
||||
*
|
||||
* @return the next token in the <code>InputStream</code>
|
||||
* @throws IllegalArgumentException
|
||||
* if <code>setInput</code> has not been called
|
||||
*/
|
||||
public Token nextToken() throws IllegalArgumentException {
|
||||
return nextToken(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next valid token from the <code>InputStream</code> given by <code>setInput</code>. This method has the ability
|
||||
* to skip over whitespace tokens by setting <code>skipWhitespace</code> to <code>true</code>.
|
||||
*
|
||||
* @param skipWhitespace
|
||||
* whether or not the lexer should skip whitespace tokens
|
||||
* @return the next token in the <code>InputStream</code>
|
||||
* @throws IllegalArgumentException
|
||||
* if <code>setInput</code> has not been called
|
||||
*/
|
||||
public Token nextToken(boolean skipWhitespace) throws IllegalArgumentException {
|
||||
if (input == null) {
|
||||
throw new IllegalArgumentException("Input cannot be null"); //$NON-NLS-1$
|
||||
}
|
||||
if (input.findWithinHorizon(TokenType.patternForAllTerminals(), 0) == null) {
|
||||
if (lastMatch != null) {
|
||||
return new Token(TokenType.EOF, "", lastMatch.end(), lastMatch.end(), currentLine, currentLineStart); //$NON-NLS-1$
|
||||
} else {
|
||||
return new Token(TokenType.EOF, "", 0, 0, 1, 0); //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
int groupNo = 1;
|
||||
for (TokenType t : TokenType.values()) {
|
||||
if (t.regex != null) {
|
||||
if (input.match().start(groupNo) != -1) {
|
||||
lastMatch = input.match();
|
||||
Token next = null;
|
||||
if (!(t.equals(TokenType.WHITESPACE) && skipWhitespace)) {
|
||||
next = new Token(t, input.match(), currentLine, currentLineStart);
|
||||
} else {
|
||||
next = nextToken(skipWhitespace);
|
||||
}
|
||||
if (t.equals(TokenType.COMMAND_END)) {
|
||||
// Advance the line number information
|
||||
currentLine++;
|
||||
currentLineStart = input.match().end();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
groupNo++;
|
||||
}
|
||||
}
|
||||
return new Token(TokenType.UNKNOWN, input.match(), currentLine, currentLineStart);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,423 @@
|
|||
/*******************************************************************************
|
||||
* 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.util.Stack;
|
||||
|
||||
import org.eclipse.cdt.internal.qt.core.location.SourceLocation;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirAST;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirASTNode;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirClassnameCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirCommentCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirDependsCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirDesignerSupportedCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirInternalCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirModuleCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirPluginCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirResourceCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirSingletonCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirSyntaxError;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirTypeInfoCommand;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirVersion;
|
||||
import org.eclipse.cdt.internal.qt.core.qmldir.QDirWord;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.Token;
|
||||
import org.eclipse.cdt.qt.core.qmldir.QMLDirectoryLexer.TokenType;
|
||||
|
||||
/**
|
||||
* Converts an <code>InputStream</code> representing a qmldir file into an Abstract Syntax Tree. Uses the {@link QMLDirectoryLexer}
|
||||
* under the hood to match tokens which it then uses to construct the AST. Also, a <code>QMLDirectoryParser</code> has the ability
|
||||
* to skip over syntax errors and include them in its AST rather than returning upon the first error.
|
||||
*/
|
||||
public class QMLDirectoryParser {
|
||||
/**
|
||||
* An exception thrown when a <code>QMLDirectoryParser</code> encounters a syntax error. This class stores information on the
|
||||
* offending token as well as the node the parser was working on before it failed (if available).
|
||||
*/
|
||||
public static class SyntaxError extends RuntimeException {
|
||||
private static final long serialVersionUID = 6608815552297970623L;
|
||||
|
||||
private final IQDirASTNode incompleteNode;
|
||||
private final Token offendingToken;
|
||||
|
||||
/**
|
||||
* Creates a new <code>SyntaxError</code>.
|
||||
*
|
||||
* @param node
|
||||
* the incomplete working node
|
||||
* @param token
|
||||
* the offending token
|
||||
* @param message
|
||||
* the message to display
|
||||
*/
|
||||
public SyntaxError(IQDirASTNode node, Token token, String message) {
|
||||
super(message);
|
||||
this.incompleteNode = node;
|
||||
this.offendingToken = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the token that caused the parser to fail.
|
||||
*
|
||||
* @return the offending token
|
||||
*/
|
||||
public Token getOffendingToken() {
|
||||
return offendingToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last node that the parser was working on before it failed or null if that information isn't present.
|
||||
*
|
||||
* @return the incomplete node or <code>null</code> if not available
|
||||
*/
|
||||
public IQDirASTNode getIncompleteNode() {
|
||||
return incompleteNode;
|
||||
}
|
||||
}
|
||||
|
||||
private final QMLDirectoryLexer lexer;
|
||||
private final Stack<QDirASTNode> workingNodes;
|
||||
private Token tok;
|
||||
|
||||
/**
|
||||
* Initializes a new <code>QMLDirectoryParser</code> capable of parsing an <code>InputStream</code> and returning an AST.
|
||||
*/
|
||||
public QMLDirectoryParser() {
|
||||
this.lexer = new QMLDirectoryLexer();
|
||||
this.workingNodes = new Stack<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given <code>InputStream</code> into an Abstract Syntax Tree. This is a helper method equivalent to
|
||||
* <code>parse(input, true)</code>. That is, the parser will attempt to recover once it hits an error and include an
|
||||
* {@link IQDirSyntaxError} node in the AST.
|
||||
*
|
||||
* @param input
|
||||
* the input to parse
|
||||
* @return the Abstract Syntax Tree representing the input
|
||||
* @see QMLDirectoryParser#parse(InputStream, boolean)
|
||||
*/
|
||||
public IQDirAST parse(InputStream input) {
|
||||
return parse(input, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given <code>InputStream</code> into an Abstract Syntax Tree. If <code>tolerateErrors</code> is <code>true</code>,
|
||||
* any syntax errors will be included in the AST as a separate {@link IQDirSyntaxErrorCommand}. The parser will then attempt to
|
||||
* recover by jumping to the next line and continue parsing. A value of </code>false</code> tells the parser to throw a
|
||||
* {@link SyntaxError} on the first problem it encounters.
|
||||
*
|
||||
* @param input
|
||||
* the input to parse
|
||||
* @param tolerateErrors
|
||||
* whether or not the parser should be error tolerant
|
||||
* @return the Abstract Syntax Tree representing the input
|
||||
*/
|
||||
public IQDirAST parse(InputStream input, boolean tolerateErrors) {
|
||||
// Clear out any leftover state
|
||||
this.lexer.setInput(input);
|
||||
this.workingNodes.clear();
|
||||
|
||||
QDirAST ast = new QDirAST();
|
||||
nextToken();
|
||||
while (tok.getType() != TokenType.EOF) {
|
||||
try {
|
||||
switch (tok.getType()) {
|
||||
case MODULE:
|
||||
ast.addCommand(parseModuleCommand());
|
||||
break;
|
||||
case SINGLETON:
|
||||
ast.addCommand(parseSingletonCommand());
|
||||
break;
|
||||
case INTERNAL:
|
||||
ast.addCommand(parseInternalCommand());
|
||||
break;
|
||||
case WORD:
|
||||
ast.addCommand(parseResourceCommand());
|
||||
break;
|
||||
case PLUGIN:
|
||||
ast.addCommand(parsePluginCommand());
|
||||
break;
|
||||
case CLASSNAME:
|
||||
ast.addCommand(parseClassnameCommand());
|
||||
break;
|
||||
case TYPEINFO:
|
||||
ast.addCommand(parseTypeInfoCommand());
|
||||
break;
|
||||
case DEPENDS:
|
||||
ast.addCommand(parseDependsCommand());
|
||||
break;
|
||||
case DESIGNERSUPPORTED:
|
||||
ast.addCommand(parseDesignerSupportedCommand());
|
||||
break;
|
||||
case COMMENT:
|
||||
ast.addCommand(parseCommentCommand());
|
||||
break;
|
||||
case COMMAND_END:
|
||||
// This is just an empty line that should be ignored
|
||||
nextToken();
|
||||
break;
|
||||
default:
|
||||
throw unexpectedToken();
|
||||
}
|
||||
} catch (SyntaxError e) {
|
||||
if (!tolerateErrors) {
|
||||
throw e;
|
||||
}
|
||||
// Add the syntax error to the AST and jump to the next line
|
||||
QDirSyntaxError errNode = new QDirSyntaxError(e);
|
||||
markStart(errNode);
|
||||
IQDirASTNode node = e.getIncompleteNode();
|
||||
if (node != null) {
|
||||
errNode.setLocation((SourceLocation) node.getLocation());
|
||||
errNode.setStart(node.getStart());
|
||||
errNode.setEnd(node.getEnd());
|
||||
}
|
||||
while (!eat(TokenType.COMMAND_END) && !eat(TokenType.EOF)) {
|
||||
nextToken();
|
||||
}
|
||||
markEnd();
|
||||
ast.addCommand(errNode);
|
||||
}
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
private void nextToken() {
|
||||
nextToken(true);
|
||||
}
|
||||
|
||||
private void nextToken(boolean skipWhitespace) {
|
||||
tok = lexer.nextToken(skipWhitespace);
|
||||
}
|
||||
|
||||
private void markStart(QDirASTNode node) {
|
||||
workingNodes.push(node);
|
||||
node.setStart(tok.getStart());
|
||||
node.setLocation(new SourceLocation());
|
||||
node.getLocation().setStart(tok.getLocation().getStart());
|
||||
}
|
||||
|
||||
private void markEnd() {
|
||||
QDirASTNode node = workingNodes.pop();
|
||||
node.setEnd(tok.getEnd());
|
||||
node.getLocation().setEnd(tok.getLocation().getEnd());
|
||||
}
|
||||
|
||||
private boolean eat(TokenType type) {
|
||||
if (tok.getType() == type) {
|
||||
nextToken();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private SyntaxError syntaxError(String message) {
|
||||
return new SyntaxError(workingNodes.peek(), tok, message + " " + tok.getLocation().getStart().toString()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private SyntaxError unexpectedToken() {
|
||||
String tokenText = tok.getText();
|
||||
if (tok.getType() == TokenType.EOF) {
|
||||
tokenText = "EOF"; //$NON-NLS-1$
|
||||
}
|
||||
return syntaxError("Unexpected token '" + tokenText + "'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
private void expect(TokenType type) {
|
||||
if (tok.getType() != type) {
|
||||
throw unexpectedToken();
|
||||
}
|
||||
nextToken();
|
||||
}
|
||||
|
||||
private void expectCommandEnd() {
|
||||
// Allow EOF to be substituted for COMMAND_END
|
||||
if (tok.getType() == TokenType.EOF) {
|
||||
nextToken();
|
||||
return;
|
||||
}
|
||||
if (tok.getType() != TokenType.COMMAND_END) {
|
||||
throw syntaxError("Expected token '\\n' or 'EOF', but saw '" + tok.getText() + "'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
nextToken();
|
||||
}
|
||||
|
||||
private QDirModuleCommand parseModuleCommand() {
|
||||
QDirModuleCommand node = new QDirModuleCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.MODULE);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setModuleIdentifier(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirSingletonCommand parseSingletonCommand() {
|
||||
QDirSingletonCommand node = new QDirSingletonCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.SINGLETON);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setTypeName(parseWord());
|
||||
if (tok.getType() == TokenType.DECIMAL) {
|
||||
node.setInitialVersion(parseVersion());
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setFile(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw unexpectedToken();
|
||||
};
|
||||
|
||||
private QDirInternalCommand parseInternalCommand() {
|
||||
QDirInternalCommand node = new QDirInternalCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.INTERNAL);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setTypeName(parseWord());
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setFile(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirResourceCommand parseResourceCommand() {
|
||||
QDirResourceCommand node = new QDirResourceCommand();
|
||||
markStart(node);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setResourceIdentifier(parseWord());
|
||||
if (tok.getType() == TokenType.DECIMAL) {
|
||||
node.setInitialVersion(parseVersion());
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setFile(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirPluginCommand parsePluginCommand() {
|
||||
QDirPluginCommand node = new QDirPluginCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.PLUGIN);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setName(parseWord());
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setPath(parseWord());
|
||||
}
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirClassnameCommand parseClassnameCommand() {
|
||||
QDirClassnameCommand node = new QDirClassnameCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.CLASSNAME);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setIdentifier(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirTypeInfoCommand parseTypeInfoCommand() {
|
||||
QDirTypeInfoCommand node = new QDirTypeInfoCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.TYPEINFO);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setFile(parseWord());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirDependsCommand parseDependsCommand() {
|
||||
QDirDependsCommand node = new QDirDependsCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.DEPENDS);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setModuleIdentifier(parseWord());
|
||||
if (tok.getType() == TokenType.DECIMAL) {
|
||||
node.setInitialVersion(parseVersion());
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirDesignerSupportedCommand parseDesignerSupportedCommand() {
|
||||
QDirDesignerSupportedCommand node = new QDirDesignerSupportedCommand();
|
||||
markStart(node);
|
||||
expect(TokenType.DESIGNERSUPPORTED);
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
|
||||
private QDirCommentCommand parseCommentCommand() {
|
||||
QDirCommentCommand node = new QDirCommentCommand();
|
||||
markStart(node);
|
||||
if (tok.getType() == TokenType.COMMENT) {
|
||||
node.setText(tok.getText());
|
||||
nextToken();
|
||||
expectCommandEnd();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirVersion parseVersion() {
|
||||
QDirVersion node = new QDirVersion();
|
||||
markStart(node);
|
||||
if (tok.getType() == TokenType.DECIMAL) {
|
||||
node.setVersionString(tok.getText());
|
||||
nextToken();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
|
||||
private QDirWord parseWord() {
|
||||
QDirWord node = new QDirWord();
|
||||
markStart(node);
|
||||
if (tok.getType() == TokenType.WORD) {
|
||||
node.setText(tok.getText());
|
||||
nextToken();
|
||||
markEnd();
|
||||
return node;
|
||||
}
|
||||
throw unexpectedToken();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue