Merge branch 'lua52'
Conflicts:
plugins/org.eclipse.ldt.ui/OSGI-INF/l10n/bundle.properties
plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/LuaProjectCreator.java
plugins/org.eclipse.ldt/META-INF/MANIFEST.MF
diff --git a/libraries/metalua/metalua/compiler/ast_to_src.mlua b/libraries/metalua/metalua/compiler/ast_to_src.mlua
index ca80a12..fd38516 100644
--- a/libraries/metalua/metalua/compiler/ast_to_src.mlua
+++ b/libraries/metalua/metalua/compiler/ast_to_src.mlua
@@ -389,6 +389,18 @@
end
end
+function M:Goto (node, name, annots)
+ print ("node",node, name); io.flush();
+ self:acc "goto "
+ self:acc (name)
+end
+
+function M:Label (node, name, annots)
+ self:acc "::"
+ self:acc (name)
+ self:acc "::"
+end
+
function M:Localrec (node, lhs, rhs)
match node with
| `Localrec{ { `Id{name} }, { `Function{ params, body } } }
diff --git a/libraries/metalua/metalua/compiler/parser/stat.lua b/libraries/metalua/metalua/compiler/parser/stat.lua
index 5d5e3a9..b262c1c 100644
--- a/libraries/metalua/metalua/compiler/parser/stat.lua
+++ b/libraries/metalua/metalua/compiler/parser/stat.lua
@@ -45,235 +45,237 @@
return function(M)
- local _M = gg.future(M)
+ local _M = gg.future(M)
- M.block_terminators = { "else", "elseif", "end", "until", ")", "}", "]" }
+ M.block_terminators = { "else", "elseif", "end", "until", ")", "}", "]" }
- -- FIXME: this must be handled from within GG!!!
- -- FIXME: there's no :add method in the list anyway. Added by gg.list?!
- function M.block_terminators :add(x)
- if type (x) == "table" then for _, y in ipairs(x) do self :add (y) end
- else table.insert (self, x) end
+ -- FIXME: this must be handled from within GG!!!
+ -- FIXME: there's no :add method in the list anyway. Added by gg.list?!
+ function M.block_terminators :add(x)
+ if type (x) == "table" then for _, y in ipairs(x) do self :add (y) end
+ else table.insert (self, x) end
+ end
+
+ ----------------------------------------------------------------------------
+ -- list of statements, possibly followed by semicolons
+ ----------------------------------------------------------------------------
+ M.block = gg.list {
+ name = "statements block",
+ terminators = M.block_terminators,
+ primary = function (lx)
+ -- FIXME use gg.optkeyword()
+ local x = M.stat (lx)
+ if lx:is_keyword (lx:peek(), ";") then lx:next() end
+ return x
+ end }
+
+ ----------------------------------------------------------------------------
+ -- Helper function for "return <expr_list>" parsing.
+ -- Called when parsing return statements.
+ -- The specific test for initial ";" is because it's not a block terminator,
+ -- so without it gg.list would choke on "return ;" statements.
+ -- We don't make a modified copy of block_terminators because this list
+ -- is sometimes modified at runtime, and the return parser would get out of
+ -- sync if it was relying on a copy.
+ ----------------------------------------------------------------------------
+ local return_expr_list_parser = gg.multisequence{
+ { ";" , builder = function() return { } end },
+ default = gg.list {
+ _M.expr, separators = ",", terminators = M.block_terminators } }
+
+
+ local for_vars_list = gg.list{
+ name = "for variables list",
+ primary = _M.id,
+ separators = ",",
+ terminators = "in" }
+
+ ----------------------------------------------------------------------------
+ -- for header, between [for] and [do] (exclusive).
+ -- Return the `Forxxx{...} AST, without the body element (the last one).
+ ----------------------------------------------------------------------------
+ function M.for_header (lx)
+ local vars = M.id_list(lx)
+ if lx :is_keyword (lx:peek(), "=") then
+ if #vars ~= 1 then
+ gg.parse_error (lx, "numeric for only accepts one variable")
+ end
+ lx:next() -- skip "="
+ local exprs = M.expr_list (lx)
+ if #exprs < 2 or #exprs > 3 then
+ gg.parse_error (lx, "numeric for requires 2 or 3 boundaries")
+ end
+ return { tag="Fornum", vars[1], unpack (exprs) }
+ else
+ if not lx :is_keyword (lx :next(), "in") then
+ gg.parse_error (lx, '"=" or "in" expected in for loop')
+ end
+ local exprs = M.expr_list (lx)
+ return { tag="Forin", vars, exprs }
end
+ end
- ----------------------------------------------------------------------------
- -- list of statements, possibly followed by semicolons
- ----------------------------------------------------------------------------
- M.block = gg.list {
- name = "statements block",
- terminators = M.block_terminators,
- primary = function (lx)
- -- FIXME use gg.optkeyword()
- local x = M.stat (lx)
- if lx:is_keyword (lx:peek(), ";") then lx:next() end
- return x
- end }
-
- ----------------------------------------------------------------------------
- -- Helper function for "return <expr_list>" parsing.
- -- Called when parsing return statements.
- -- The specific test for initial ";" is because it's not a block terminator,
- -- so without it gg.list would choke on "return ;" statements.
- -- We don't make a modified copy of block_terminators because this list
- -- is sometimes modified at runtime, and the return parser would get out of
- -- sync if it was relying on a copy.
- ----------------------------------------------------------------------------
- local return_expr_list_parser = gg.multisequence{
- { ";" , builder = function() return { } end },
- default = gg.list {
- _M.expr, separators = ",", terminators = M.block_terminators } }
-
-
- local for_vars_list = gg.list{
- name = "for variables list",
- primary = _M.id,
- separators = ",",
- terminators = "in" }
-
- ----------------------------------------------------------------------------
- -- for header, between [for] and [do] (exclusive).
- -- Return the `Forxxx{...} AST, without the body element (the last one).
- ----------------------------------------------------------------------------
- function M.for_header (lx)
- local vars = M.id_list(lx)
- if lx :is_keyword (lx:peek(), "=") then
- if #vars ~= 1 then
- gg.parse_error (lx, "numeric for only accepts one variable")
- end
- lx:next() -- skip "="
- local exprs = M.expr_list (lx)
- if #exprs < 2 or #exprs > 3 then
- gg.parse_error (lx, "numeric for requires 2 or 3 boundaries")
- end
- return { tag="Fornum", vars[1], unpack (exprs) }
- else
- if not lx :is_keyword (lx :next(), "in") then
- gg.parse_error (lx, '"=" or "in" expected in for loop')
- end
- local exprs = M.expr_list (lx)
- return { tag="Forin", vars, exprs }
- end
+ ----------------------------------------------------------------------------
+ -- Function def parser helper: id ( . id ) *
+ ----------------------------------------------------------------------------
+ local function fn_builder (list)
+ local acc = list[1]
+ local first = acc.lineinfo.first
+ for i = 2, #list do
+ local index = M.id2string(list[i])
+ local li = lexer.new_lineinfo(first, index.lineinfo.last)
+ acc = { tag="Index", acc, index, lineinfo=li }
end
+ return acc
+ end
+ local func_name = gg.list{ _M.id, separators = ".", builder = fn_builder }
- ----------------------------------------------------------------------------
- -- Function def parser helper: id ( . id ) *
- ----------------------------------------------------------------------------
- local function fn_builder (list)
- local acc = list[1]
- local first = acc.lineinfo.first
- for i = 2, #list do
- local index = M.id2string(list[i])
- local li = lexer.new_lineinfo(first, index.lineinfo.last)
- acc = { tag="Index", acc, index, lineinfo=li }
- end
- return acc
+ ----------------------------------------------------------------------------
+ -- Function def parser helper: ( : id )?
+ ----------------------------------------------------------------------------
+ local method_name = gg.onkeyword{ name = "method invocation", ":", _M.id,
+ transformers = { function(x) return x and x.tag=='Id' and M.id2string(x) end } }
+
+ ----------------------------------------------------------------------------
+ -- Function def builder
+ ----------------------------------------------------------------------------
+ local function funcdef_builder(x)
+ local name, method, func = unpack(x)
+ if method then
+ name = { tag="Index", name, method,
+ lineinfo = {
+ first = name.lineinfo.first,
+ last = method.lineinfo.last } }
+ table.insert (func[1], 1, {tag="Id", "self"})
end
- local func_name = gg.list{ _M.id, separators = ".", builder = fn_builder }
+ local r = { tag="Set", {name}, {func} }
+ r[1].lineinfo = name.lineinfo
+ r[2].lineinfo = func.lineinfo
+ return r
+ end
- ----------------------------------------------------------------------------
- -- Function def parser helper: ( : id )?
- ----------------------------------------------------------------------------
- local method_name = gg.onkeyword{ name = "method invocation", ":", _M.id,
- transformers = { function(x) return x and x.tag=='Id' and M.id2string(x) end } }
- ----------------------------------------------------------------------------
- -- Function def builder
- ----------------------------------------------------------------------------
- local function funcdef_builder(x)
- local name, method, func = unpack(x)
- if method then
- name = { tag="Index", name, method,
- lineinfo = {
- first = name.lineinfo.first,
- last = method.lineinfo.last } }
- table.insert (func[1], 1, {tag="Id", "self"})
- end
- local r = { tag="Set", {name}, {func} }
- r[1].lineinfo = name.lineinfo
- r[2].lineinfo = func.lineinfo
- return r
+ ----------------------------------------------------------------------------
+ -- if statement builder
+ ----------------------------------------------------------------------------
+ local function if_builder (x)
+ local cond_block_pairs, else_block, r = x[1], x[2], {tag="If"}
+ local n_pairs = #cond_block_pairs
+ for i = 1, n_pairs do
+ local cond, block = unpack(cond_block_pairs[i])
+ r[2*i-1], r[2*i] = cond, block
end
+ if else_block then table.insert(r, #r+1, else_block) end
+ return r
+ end
+ --------------------------------------------------------------------------------
+ -- produce a list of (expr,block) pairs
+ --------------------------------------------------------------------------------
+ local elseifs_parser = gg.list {
+ gg.sequence { _M.expr, "then", _M.block , name='elseif parser' },
+ separators = "elseif",
+ terminators = { "else", "end" }
+ }
- ----------------------------------------------------------------------------
- -- if statement builder
- ----------------------------------------------------------------------------
- local function if_builder (x)
- local cond_block_pairs, else_block, r = x[1], x[2], {tag="If"}
- local n_pairs = #cond_block_pairs
- for i = 1, n_pairs do
- local cond, block = unpack(cond_block_pairs[i])
- r[2*i-1], r[2*i] = cond, block
- end
- if else_block then table.insert(r, #r+1, else_block) end
- return r
+ local annot_expr = gg.sequence {
+ _M.expr,
+ gg.onkeyword{ "#", gg.future(M, 'annot').tf },
+ builder = function(x)
+ local e, a = unpack(x)
+ if a then return { tag='Annot', e, a }
+ else return e end
+ end }
+
+ local annot_expr_list = gg.list {
+ primary = annot.opt(M, _M.expr, 'tf'), separators = ',' }
+
+ ------------------------------------------------------------------------
+ -- assignments and calls: statements that don't start with a keyword
+ ------------------------------------------------------------------------
+ local function assign_or_call_stat_parser (lx)
+ local e = annot_expr_list (lx)
+ local a = lx:is_keyword(lx:peek())
+ local op = a and M.assignments[a]
+ -- TODO: refactor annotations
+ if op then
+ --FIXME: check that [e] is a LHS
+ lx :next()
+ local annots
+ e, annots = annot.split(e)
+ local v = M.expr_list (lx)
+ if type(op)=="string" then return { tag=op, e, v, annots }
+ else return op (e, v) end
+ else
+ assert (#e > 0)
+ if #e > 1 then
+ gg.parse_error (lx,
+ "comma is not a valid statement separator; statement can be "..
+ "separated by semicolons, or not separated at all")
+ elseif e[1].tag ~= "Call" and e[1].tag ~= "Invoke" then
+ local typename
+ if e[1].tag == 'Id' then
+ typename = '("'..e[1][1]..'") is an identifier'
+ elseif e[1].tag == 'Op' then
+ typename = "is an arithmetic operation"
+ else typename = "is of type '"..(e[1].tag or "<list>").."'" end
+ gg.parse_error (lx,
+ "This expression %s; "..
+ "a statement was expected, and only function and method call "..
+ "expressions can be used as statements", typename);
+ end
+ return e[1]
end
+ end
- --------------------------------------------------------------------------------
- -- produce a list of (expr,block) pairs
- --------------------------------------------------------------------------------
- local elseifs_parser = gg.list {
- gg.sequence { _M.expr, "then", _M.block , name='elseif parser' },
- separators = "elseif",
- terminators = { "else", "end" }
- }
+ M.local_stat_parser = gg.multisequence{
+ -- local function <name> <func_val>
+ { "function", _M.id, _M.func_val, builder =
+ function(x)
+ local vars = { x[1], lineinfo = x[1].lineinfo }
+ local vals = { x[2], lineinfo = x[2].lineinfo }
+ return { tag="Localrec", vars, vals }
+ end },
+ -- local <id_list> ( = <expr_list> )?
+ default = gg.sequence{
+ gg.list{
+ primary = annot.opt(M, _M.id, 'tf'),
+ separators = ',' },
+ gg.onkeyword{ "=", _M.expr_list },
+ builder = function(x)
+ local annotated_left, right = unpack(x)
+ local left, annotations = annot.split(annotated_left)
+ return {tag="Local", left, right or { }, annotations }
+ end } }
- local annot_expr = gg.sequence {
- _M.expr,
- gg.onkeyword{ "#", gg.future(M, 'annot').tf },
- builder = function(x)
- local e, a = unpack(x)
- if a then return { tag='Annot', e, a }
- else return e end
- end }
+ ------------------------------------------------------------------------
+ -- statement
+ ------------------------------------------------------------------------
+ M.stat = gg.multisequence {
+ name = "statement",
+ { "do", _M.block, "end", builder =
+ function (x) return { tag="Do", unpack (x[1]) } end },
+ { "for", _M.for_header, "do", _M.block, "end", builder =
+ function (x) x[1][#x[1]+1] = x[2]; return x[1] end },
+ { "function", func_name, method_name, _M.func_val, builder=funcdef_builder },
+ { "while", _M.expr, "do", _M.block, "end", builder = "While" },
+ { "repeat", _M.block, "until", _M.expr, builder = "Repeat" },
+ { "goto", _M.id, builder = function(x) return {tag='Goto',x[1]} end },
+ { "::",_M.id,"::", builder = function(x) return {tag='Label',x[1]} end },
+ { "local", _M.local_stat_parser, builder = unpack },
+ { "return", return_expr_list_parser, builder =
+ function(x) x[1].tag='Return'; return x[1] end },
+ { "break", builder = function() return { tag="Break" } end },
+ { "-{", gg.future(M, 'meta').splice_content, "}", builder = unpack },
+ { "if", gg.nonempty(elseifs_parser), gg.onkeyword{ "else", M.block }, "end",
+ builder = if_builder },
+ default = assign_or_call_stat_parser }
- local annot_expr_list = gg.list {
- primary = annot.opt(M, _M.expr, 'tf'), separators = ',' }
+ M.assignments = {
+ ["="] = "Set"
+ }
- ------------------------------------------------------------------------
- -- assignments and calls: statements that don't start with a keyword
- ------------------------------------------------------------------------
- local function assign_or_call_stat_parser (lx)
- local e = annot_expr_list (lx)
- local a = lx:is_keyword(lx:peek())
- local op = a and M.assignments[a]
- -- TODO: refactor annotations
- if op then
- --FIXME: check that [e] is a LHS
- lx :next()
- local annots
- e, annots = annot.split(e)
- local v = M.expr_list (lx)
- if type(op)=="string" then return { tag=op, e, v, annots }
- else return op (e, v) end
- else
- assert (#e > 0)
- if #e > 1 then
- gg.parse_error (lx,
- "comma is not a valid statement separator; statement can be "..
- "separated by semicolons, or not separated at all")
- elseif e[1].tag ~= "Call" and e[1].tag ~= "Invoke" then
- local typename
- if e[1].tag == 'Id' then
- typename = '("'..e[1][1]..'") is an identifier'
- elseif e[1].tag == 'Op' then
- typename = "is an arithmetic operation"
- else typename = "is of type '"..(e[1].tag or "<list>").."'" end
- gg.parse_error (lx,
- "This expression %s; "..
- "a statement was expected, and only function and method call "..
- "expressions can be used as statements", typename);
- end
- return e[1]
- end
- end
+ function M.assignments:add(k, v) self[k] = v end
- M.local_stat_parser = gg.multisequence{
- -- local function <name> <func_val>
- { "function", _M.id, _M.func_val, builder =
- function(x)
- local vars = { x[1], lineinfo = x[1].lineinfo }
- local vals = { x[2], lineinfo = x[2].lineinfo }
- return { tag="Localrec", vars, vals }
- end },
- -- local <id_list> ( = <expr_list> )?
- default = gg.sequence{
- gg.list{
- primary = annot.opt(M, _M.id, 'tf'),
- separators = ',' },
- gg.onkeyword{ "=", _M.expr_list },
- builder = function(x)
- local annotated_left, right = unpack(x)
- local left, annotations = annot.split(annotated_left)
- return {tag="Local", left, right or { }, annotations }
- end } }
-
- ------------------------------------------------------------------------
- -- statement
- ------------------------------------------------------------------------
- M.stat = gg.multisequence {
- name = "statement",
- { "do", _M.block, "end", builder =
- function (x) return { tag="Do", unpack (x[1]) } end },
- { "for", _M.for_header, "do", _M.block, "end", builder =
- function (x) x[1][#x[1]+1] = x[2]; return x[1] end },
- { "function", func_name, method_name, _M.func_val, builder=funcdef_builder },
- { "while", _M.expr, "do", _M.block, "end", builder = "While" },
- { "repeat", _M.block, "until", _M.expr, builder = "Repeat" },
- { "local", _M.local_stat_parser, builder = unpack },
- { "return", return_expr_list_parser, builder =
- function(x) x[1].tag='Return'; return x[1] end },
- { "break", builder = function() return { tag="Break" } end },
- { "-{", gg.future(M, 'meta').splice_content, "}", builder = unpack },
- { "if", gg.nonempty(elseifs_parser), gg.onkeyword{ "else", M.block }, "end",
- builder = if_builder },
- default = assign_or_call_stat_parser }
-
- M.assignments = {
- ["="] = "Set"
- }
-
- function M.assignments:add(k, v) self[k] = v end
-
- return M
-end
\ No newline at end of file
+ return M
+end
diff --git a/plugins/com.naef.jnlua-lua52/META-INF/MANIFEST.MF b/plugins/com.naef.jnlua-lua52/META-INF/MANIFEST.MF
index d3e1635..1fe6418 100644
--- a/plugins/com.naef.jnlua-lua52/META-INF/MANIFEST.MF
+++ b/plugins/com.naef.jnlua-lua52/META-INF/MANIFEST.MF
@@ -12,6 +12,7 @@
Bundle-ActivationPolicy: lazy
Export-Package: com.naef.jnlua,
com.naef.jnlua.console,
+ com.naef.jnlua.eclipse,
com.naef.jnlua.internal.osgi,
com.naef.jnlua.script,
com.naef.jnlua.util
diff --git a/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/eclipse/AbstractLuaModule.java b/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/eclipse/AbstractLuaModule.java
new file mode 100644
index 0000000..e4eb8a5
--- /dev/null
+++ b/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/eclipse/AbstractLuaModule.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package com.naef.jnlua.eclipse;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.Bundle;
+
+import com.naef.jnlua.LuaState;
+import com.naef.jnlua.internal.osgi.Activator;
+
+/**
+ * Abstract class to manipulate Lua module
+ */
+public abstract class AbstractLuaModule {
+
+ private static final String LUA_PATTERN = "?.lua;"; //$NON-NLS-1$
+ private static final String LUAC_PATTERN = "?.luac;"; //$NON-NLS-1$
+
+ private Map<String, File> foldersCache = new HashMap<String, File>();
+
+ protected void definePaths(final LuaState luaState) {
+ // set lua path
+ final List<File> luaSourceFolders = getScriptFolders(getLuaSourcePaths());
+ final List<File> luacSourceFolders = getScriptFolders(getLuacSourcePaths());
+ setLuaPath(luaState, luaSourceFolders, luacSourceFolders);
+ }
+
+ /**
+ * load the module with the name return by moduleName and store it in global var module name
+ */
+ protected LuaState loadLuaModule() {
+ // get lua state
+ LuaState luaState = createLuaState();
+ definePaths(luaState);
+
+ // load module
+ luaState.getGlobal("require"); //$NON-NLS-1$
+ luaState.pushString(getModuleName());
+ luaState.call(1, 1);
+ luaState.setGlobal(getModuleName());
+
+ return luaState;
+ }
+
+ protected void pushLuaModule(LuaState luaState) {
+ luaState.getGlobal(getModuleName());
+ }
+
+ /**
+ * return all the script folders
+ */
+ protected List<File> getScriptFolders(List<String> folderRelativePaths) {
+ List<File> scriptFolders = new ArrayList<File>();
+ if (folderRelativePaths != null) {
+ for (String folderRelativePath : folderRelativePaths) {
+ File scriptFolder = getScriptFolder(folderRelativePath);
+ if (scriptFolder != null)
+ scriptFolders.add(scriptFolder);
+ }
+ }
+ return scriptFolders;
+ }
+
+ /**
+ * return the folder in the bundle (pluginID) at the relative path
+ */
+ protected File getScriptFolder(String relativepath) {
+ File folder = foldersCache.get(relativepath);
+ if (folder == null) {
+ try {
+ // extract file from bundle and get url
+ final URL folderUrl = FileLocator.toFileURL(Platform.getBundle(getPluginID()).getEntry(relativepath));
+ folder = new File(folderUrl.getFile());
+ foldersCache.put(relativepath, folder);
+ } catch (final IOException e) {
+ final String message = NLS.bind("Unable to get entry {0} in the plugin {1}.", relativepath, getPluginID());
+ log(IStatus.ERROR, message, e);
+ }
+ }
+ return folder;
+ }
+
+ /**
+ * Add the given folders to the lua path
+ */
+ public static void setLuaPath(LuaState luaState, List<File> luafolders, List<File> luacfolders) {
+ // Change path
+ final StringBuffer code = new StringBuffer("package.path=[["); //$NON-NLS-1$
+ for (File folder : luafolders) {
+ code.append(folder.getPath());
+ code.append(File.separatorChar);
+ code.append(LUA_PATTERN);
+ }
+ for (File folder : luacfolders) {
+ code.append(folder.getPath());
+ code.append(File.separatorChar);
+ code.append(LUAC_PATTERN);
+ }
+ code.append("]]..package.path"); //$NON-NLS-1$
+ luaState.load(code.toString(), "reloadingPath"); //$NON-NLS-1$
+ luaState.call(0, 0);
+ }
+
+ protected abstract List<String> getLuaSourcePaths();
+
+ protected abstract List<String> getLuacSourcePaths();
+
+ protected abstract LuaState createLuaState();
+
+ protected abstract String getPluginID();
+
+ protected abstract String getModuleName();
+
+ protected static void log(int severity, String message, Throwable throwable) {
+ // we use a 'special' way to log (without the org.eclipse.core.runtime.Plugin)
+ // because we want eclipse dependencie only for this package
+ Bundle bundle = Platform.getBundle(Activator.BUNDLEID);
+ if (bundle != null) {
+ ILog log = Platform.getLog(bundle);
+ if (log != null) {
+ log.log(new Status(severity, Activator.BUNDLEID, message, throwable));
+ }
+ }
+ }
+}
diff --git a/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/internal/osgi/Activator.java b/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/internal/osgi/Activator.java
index fe3f3f2..4043e65 100644
--- a/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/internal/osgi/Activator.java
+++ b/plugins/com.naef.jnlua-lua52/src/com/naef/jnlua/internal/osgi/Activator.java
@@ -5,6 +5,8 @@
public class Activator implements BundleActivator {
+ public static final String BUNDLEID = "com.naef.jnlua";
+
private static BundleContext context;
static BundleContext getContext() {
@@ -13,11 +15,14 @@
/*
* (non-Javadoc)
- * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ *
+ * @see
+ * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+ * )
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
-
+
// fixes a problem with binary interdependencies: a library cannot find
// its dependencies if they're inside the bundle
System.loadLibrary("lua52");
@@ -25,7 +30,9 @@
/*
* (non-Javadoc)
- * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ *
+ * @see
+ * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
diff --git a/plugins/org.eclipse.ldt.support.lua51/META-INF/MANIFEST.MF b/plugins/org.eclipse.ldt.support.lua51/META-INF/MANIFEST.MF
index 044186d..92adc8f 100644
--- a/plugins/org.eclipse.ldt.support.lua51/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.ldt.support.lua51/META-INF/MANIFEST.MF
@@ -17,5 +17,6 @@
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: org.eclipse.ldt.support.lua51.internal;x-internal:=true,
- org.eclipse.ldt.support.lua51.internal.interpreter;x-internal:=true
+ org.eclipse.ldt.support.lua51.internal.interpreter;x-internal:=true,
+ org.eclipse.ldt.support.lua51.internal.validator;x-internal:=true
diff --git a/plugins/org.eclipse.ldt.support.lua51/build.properties b/plugins/org.eclipse.ldt.support.lua51/build.properties
index e6890ed..2073d00 100644
--- a/plugins/org.eclipse.ldt.support.lua51/build.properties
+++ b/plugins/org.eclipse.ldt.support.lua51/build.properties
@@ -16,7 +16,8 @@
about.html,\
resource/,\
OSGI-INF/l10n/bundle.properties,\
- OSGI-INF/
+ OSGI-INF/,\
+ script/
# The java version of the source code
javacSource=1.6
# The java version of the byte code targeted
diff --git a/plugins/org.eclipse.ldt.support.lua51/plugin.xml b/plugins/org.eclipse.ldt.support.lua51/plugin.xml
index 6dd00f6..e5124d7 100644
--- a/plugins/org.eclipse.ldt.support.lua51/plugin.xml
+++ b/plugins/org.eclipse.ldt.support.lua51/plugin.xml
@@ -39,4 +39,12 @@
name="Lua 5.1 on JNLua">
</interpreterInstall>
</extension>
+ <extension
+ point="org.eclipse.ldt.luaGrammar">
+ <grammar
+ keywords="and,break,do,else,elseif,end,false,for,function,if,in,local,nil,not,or,repeat,return,then,true,until,while"
+ name="lua-5.1"
+ validator="org.eclipse.ldt.support.lua51.internal.validator.Lua51SourceValidator">
+ </grammar>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.ldt.support.lua51/script/internal/lua51validator.lua b/plugins/org.eclipse.ldt.support.lua51/script/internal/lua51validator.lua
new file mode 100644
index 0000000..6b09490
--- /dev/null
+++ b/plugins/org.eclipse.ldt.support.lua51/script/internal/lua51validator.lua
@@ -0,0 +1,106 @@
+local M = {}
+
+function M.valid (source, root)
+ -- manage shebang
+ if source then source = source:gsub("^(#.-\n)", function (s) return string.rep(' ',string.len(s)) end) end
+
+ -- check for errors
+ local f, err = loadstring(source,'source_to_check')
+ local errmessage, lineindex
+
+ if not f then
+ lineindex, errmessage = string.match(err,"%[string \"source_to_check\"%]:(%d+):(.*)")
+ errmessage = errmessage or err
+ lineindex = lineindex and tonumber(lineindex) or 1
+
+ -- -------------------------------------------------
+ -- EXPERIMENTAL CODE : we try to remove faulty code
+ -- -------------------------------------------------
+ local nbline = select(2, source:gsub('\n', '\n'))+1
+ if source and nbline > 1 then
+ -- define function that replace all character of a given line in space characters
+ local function cleanline (source, linetoclean,nbline)
+ local cleanedsource
+ local iscleaned = false
+ if linetoclean == nbline then
+ -- manage last line
+ cleanedsource = source:gsub('([^\n]-)$',function (lastline)
+ iscleaned = true
+ return string.rep(' ',string.len(lastline))
+ end)
+ elseif linetoclean == 1 then
+ -- manage first line
+ cleanedsource = source:gsub('^(.-)\n',function (firstline)
+ iscleaned = true
+ return string.rep(' ',string.len(firstline)).."\n"
+ end)
+ elseif linetoclean > 1 then
+ -- manage other case
+ cleanedsource = source:gsub('^('..string.rep(".-\n",linetoclean-1)..')(.-)\n',function (start,faultyline)
+ iscleaned = true
+ return start..string.rep(' ',string.len(faultyline)) .. "\n"
+ end)
+ end
+ return cleanedsource, iscleaned
+ end
+
+ local cleanedsource
+ local iscleaned = false
+ if lineindex == 1 then
+ -- FIRST LINE CASE : error is on line 1, just clean this line and check for errors
+ cleanedsource, iscleaned = cleanline(source,1,nbline)
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ else
+ -- OTHER CASES: first, cleaning ...
+ -- if something is not closed we try to remove the line where it is opened.
+ local linestart = string.match(err,"%(to close .* at line (%d+)%)")
+ if linestart then
+ cleanedsource, iscleaned = cleanline(source,tonumber(linestart),nbline)
+ elseif lineindex > 1 then
+ -- in other case, we try to remove the "real" code line before the error
+ -- so, we start by finding the "real" line:
+ local realcodelineindex = nil
+ for i=lineindex-1,1,-1 do
+ -- we go from the line just before the error to the first line, searching a "real" code line.
+ -- (no empty line or single comment line, we do not manage multiline comment)
+ local codeline = source:match('^'..string.rep(".-\n",i-1)..'(.-)\n')
+ if codeline and not codeline:find('^%s*$') and not codeline:find('^%s*%-%-.*$') then
+ realcodelineindex = i
+ break
+ end
+ end
+ if realcodelineindex then
+ cleanedsource, iscleaned = cleanline(source,realcodelineindex,nbline)
+ end
+ end
+
+ -- after cleaning, recheck hoping there are no errors.
+ if iscleaned then
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ -- if it fail, we try to remove the line in error
+ if not f then
+ cleanedsource = cleanline(source,lineindex,nbline)
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ end
+ end
+ end
+
+ -- take cleaned source as source
+ if f then
+ source = cleanedsource
+ end
+ end
+ -- ------------------------------------------------
+ -- END OF EXPERIMENTAL CODE
+ -- -------------------------------------------------
+ end
+
+ -- return only valid source code
+ if f then
+ return source, errmessage, lineindex
+ else
+ return nil, errmessage,lineindex
+ end
+end
+
+return M
diff --git a/plugins/org.eclipse.ldt.support.lua51/src/org/eclipse/ldt/support/lua51/internal/validator/Lua51SourceValidator.java b/plugins/org.eclipse.ldt.support.lua51/src/org/eclipse/ldt/support/lua51/internal/validator/Lua51SourceValidator.java
new file mode 100644
index 0000000..a6afa55
--- /dev/null
+++ b/plugins/org.eclipse.ldt.support.lua51/src/org/eclipse/ldt/support/lua51/internal/validator/Lua51SourceValidator.java
@@ -0,0 +1,122 @@
+package org.eclipse.ldt.support.lua51.internal.validator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ldt.core.grammar.ILuaSourceValidator;
+import org.eclipse.ldt.support.lua51.internal.Activator;
+
+import com.naef.jnlua.LuaRuntimeException;
+import com.naef.jnlua.LuaState;
+import com.naef.jnlua.eclipse.AbstractLuaModule;
+
+public class Lua51SourceValidator extends AbstractLuaModule implements ILuaSourceValidator {
+
+ private static final String VALIDATOR_PATH = "script/internal"; //$NON-NLS-1$
+ private static final String MODULE_NAME = "lua51validator"; //$NON-NLS-1$
+ private static final String VALIDATION_FUNCTION = "valid"; //$NON-NLS-1$
+
+ private LuaState lua;
+
+ private String cleanedSource;
+ private String errorMessage;
+ private int lineIndex;
+
+ public Lua51SourceValidator() {
+ }
+
+ @Override
+ public boolean valid(String source) {
+ // Load function
+ if (lua == null)
+ lua = loadLuaModule();
+
+ pushLuaModule(lua);
+ lua.getField(-1, VALIDATION_FUNCTION);
+ lua.pushString(source);
+ try {
+ lua.call(1, 3);
+ } catch (final LuaRuntimeException e) {
+ Activator.logWarning("validation 5.1 failed", e); //$NON-NLS-1$
+ cleanedSource = null;
+ errorMessage = "Unexpected error ..."; //$NON-NLS-1$
+ lineIndex = 0;
+ return false;
+ }
+
+ cleanedSource = lua.toString(-3);
+ errorMessage = lua.toString(-2);
+ lineIndex = Math.max(lua.toInteger(-1) - 1, 0);
+
+ return errorMessage == null;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getLuaSourcePaths()
+ */
+ @Override
+ protected List<String> getLuaSourcePaths() {
+ ArrayList<String> sourcepaths = new ArrayList<String>();
+ sourcepaths.add(VALIDATOR_PATH);
+ return sourcepaths;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getLuacSourcePaths()
+ */
+ @Override
+ protected List<String> getLuacSourcePaths() {
+ return null;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#createLuaState()
+ */
+ @Override
+ protected LuaState createLuaState() {
+ LuaState l = new LuaState();
+ l.openLibs();
+ return l;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getPluginID()
+ */
+ @Override
+ protected String getPluginID() {
+ return Activator.PLUGIN_ID;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getModuleName()
+ */
+ @Override
+ protected String getModuleName() {
+ return MODULE_NAME;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getCleanedSource()
+ */
+ @Override
+ public String getCleanedSource() {
+ return cleanedSource;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getErrorMessage()
+ */
+ @Override
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getLineIndex()
+ */
+ @Override
+ public int getLineIndex() {
+ return lineIndex;
+ }
+
+}
diff --git a/plugins/org.eclipse.ldt.support.lua52/META-INF/MANIFEST.MF b/plugins/org.eclipse.ldt.support.lua52/META-INF/MANIFEST.MF
index 35f6d3e..2501e74 100644
--- a/plugins/org.eclipse.ldt.support.lua52/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.ldt.support.lua52/META-INF/MANIFEST.MF
@@ -17,5 +17,6 @@
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: org.eclipse.ldt.support.lua52.internal;x-internal:=true,
- org.eclipse.ldt.support.lua52.internal.interpreter;x-internal:=true
+ org.eclipse.ldt.support.lua52.internal.interpreter;x-internal:=true,
+ org.eclipse.ldt.support.lua52.internal.validator;x-internal:=true
diff --git a/plugins/org.eclipse.ldt.support.lua52/build.properties b/plugins/org.eclipse.ldt.support.lua52/build.properties
index ffaaac7..b38170b 100644
--- a/plugins/org.eclipse.ldt.support.lua52/build.properties
+++ b/plugins/org.eclipse.ldt.support.lua52/build.properties
@@ -16,7 +16,8 @@
about.html,\
resource/,\
OSGI-INF/l10n/bundle.properties,\
- OSGI-INF/
+ OSGI-INF/,\
+ script/
# The java version of the source code
javacSource=1.6
# The java version of the byte code targeted
diff --git a/plugins/org.eclipse.ldt.support.lua52/plugin.xml b/plugins/org.eclipse.ldt.support.lua52/plugin.xml
index 35464b1..6f0d6ad 100644
--- a/plugins/org.eclipse.ldt.support.lua52/plugin.xml
+++ b/plugins/org.eclipse.ldt.support.lua52/plugin.xml
@@ -39,4 +39,12 @@
name="Lua 5.2 on JNLua">
</interpreterInstall>
</extension>
+ <extension
+ point="org.eclipse.ldt.luaGrammar">
+ <grammar
+ keywords="goto,::,and,break,do,else,elseif,end,false,for,function,if,in,local,nil,not,or,repeat,return,then,true,until,while"
+ name="lua-5.2"
+ validator="org.eclipse.ldt.support.lua52.internal.validator.Lua52SourceValidator">
+ </grammar>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.ldt.support.lua52/script/internal/lua52validator.lua b/plugins/org.eclipse.ldt.support.lua52/script/internal/lua52validator.lua
new file mode 100644
index 0000000..6b09490
--- /dev/null
+++ b/plugins/org.eclipse.ldt.support.lua52/script/internal/lua52validator.lua
@@ -0,0 +1,106 @@
+local M = {}
+
+function M.valid (source, root)
+ -- manage shebang
+ if source then source = source:gsub("^(#.-\n)", function (s) return string.rep(' ',string.len(s)) end) end
+
+ -- check for errors
+ local f, err = loadstring(source,'source_to_check')
+ local errmessage, lineindex
+
+ if not f then
+ lineindex, errmessage = string.match(err,"%[string \"source_to_check\"%]:(%d+):(.*)")
+ errmessage = errmessage or err
+ lineindex = lineindex and tonumber(lineindex) or 1
+
+ -- -------------------------------------------------
+ -- EXPERIMENTAL CODE : we try to remove faulty code
+ -- -------------------------------------------------
+ local nbline = select(2, source:gsub('\n', '\n'))+1
+ if source and nbline > 1 then
+ -- define function that replace all character of a given line in space characters
+ local function cleanline (source, linetoclean,nbline)
+ local cleanedsource
+ local iscleaned = false
+ if linetoclean == nbline then
+ -- manage last line
+ cleanedsource = source:gsub('([^\n]-)$',function (lastline)
+ iscleaned = true
+ return string.rep(' ',string.len(lastline))
+ end)
+ elseif linetoclean == 1 then
+ -- manage first line
+ cleanedsource = source:gsub('^(.-)\n',function (firstline)
+ iscleaned = true
+ return string.rep(' ',string.len(firstline)).."\n"
+ end)
+ elseif linetoclean > 1 then
+ -- manage other case
+ cleanedsource = source:gsub('^('..string.rep(".-\n",linetoclean-1)..')(.-)\n',function (start,faultyline)
+ iscleaned = true
+ return start..string.rep(' ',string.len(faultyline)) .. "\n"
+ end)
+ end
+ return cleanedsource, iscleaned
+ end
+
+ local cleanedsource
+ local iscleaned = false
+ if lineindex == 1 then
+ -- FIRST LINE CASE : error is on line 1, just clean this line and check for errors
+ cleanedsource, iscleaned = cleanline(source,1,nbline)
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ else
+ -- OTHER CASES: first, cleaning ...
+ -- if something is not closed we try to remove the line where it is opened.
+ local linestart = string.match(err,"%(to close .* at line (%d+)%)")
+ if linestart then
+ cleanedsource, iscleaned = cleanline(source,tonumber(linestart),nbline)
+ elseif lineindex > 1 then
+ -- in other case, we try to remove the "real" code line before the error
+ -- so, we start by finding the "real" line:
+ local realcodelineindex = nil
+ for i=lineindex-1,1,-1 do
+ -- we go from the line just before the error to the first line, searching a "real" code line.
+ -- (no empty line or single comment line, we do not manage multiline comment)
+ local codeline = source:match('^'..string.rep(".-\n",i-1)..'(.-)\n')
+ if codeline and not codeline:find('^%s*$') and not codeline:find('^%s*%-%-.*$') then
+ realcodelineindex = i
+ break
+ end
+ end
+ if realcodelineindex then
+ cleanedsource, iscleaned = cleanline(source,realcodelineindex,nbline)
+ end
+ end
+
+ -- after cleaning, recheck hoping there are no errors.
+ if iscleaned then
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ -- if it fail, we try to remove the line in error
+ if not f then
+ cleanedsource = cleanline(source,lineindex,nbline)
+ f, _ = loadstring(cleanedsource,'source_to_check')
+ end
+ end
+ end
+
+ -- take cleaned source as source
+ if f then
+ source = cleanedsource
+ end
+ end
+ -- ------------------------------------------------
+ -- END OF EXPERIMENTAL CODE
+ -- -------------------------------------------------
+ end
+
+ -- return only valid source code
+ if f then
+ return source, errmessage, lineindex
+ else
+ return nil, errmessage,lineindex
+ end
+end
+
+return M
diff --git a/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/Activator.java b/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/Activator.java
index 7f6da5d..afa85a0 100644
--- a/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/Activator.java
+++ b/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/Activator.java
@@ -18,7 +18,7 @@
public class Activator extends Plugin {
/** The plug-in ID */
- public static final String PLUGIN_ID = "org.eclipse.ldt.support.lua51"; //$NON-NLS-1$
+ public static final String PLUGIN_ID = "org.eclipse.ldt.support.lua52"; //$NON-NLS-1$
/** The shared instance */
private static Activator plugin;
diff --git a/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/validator/Lua52SourceValidator.java b/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/validator/Lua52SourceValidator.java
new file mode 100644
index 0000000..4c220c9
--- /dev/null
+++ b/plugins/org.eclipse.ldt.support.lua52/src/org/eclipse/ldt/support/lua52/internal/validator/Lua52SourceValidator.java
@@ -0,0 +1,122 @@
+package org.eclipse.ldt.support.lua52.internal.validator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ldt.core.grammar.ILuaSourceValidator;
+import org.eclipse.ldt.support.lua52.internal.Activator;
+
+import com.naef.jnlua.LuaRuntimeException;
+import com.naef.jnlua.LuaState;
+import com.naef.jnlua.eclipse.AbstractLuaModule;
+
+public class Lua52SourceValidator extends AbstractLuaModule implements ILuaSourceValidator {
+
+ private static final String VALIDATOR_PATH = "script/internal"; //$NON-NLS-1$
+ private static final String MODULE_NAME = "lua52validator"; //$NON-NLS-1$
+ private static final String VALIDATION_FUNCTION = "valid"; //$NON-NLS-1$
+
+ private LuaState lua;
+
+ private String cleanedSource;
+ private String errorMessage;
+ private int lineIndex;
+
+ public Lua52SourceValidator() {
+ }
+
+ @Override
+ public boolean valid(String source) {
+ // Load function
+ if (lua == null)
+ lua = loadLuaModule();
+
+ pushLuaModule(lua);
+ lua.getField(-1, VALIDATION_FUNCTION);
+ lua.pushString(source);
+ try {
+ lua.call(1, 3);
+ } catch (final LuaRuntimeException e) {
+ Activator.logWarning("validation 5.2 failed", e); //$NON-NLS-1$
+ cleanedSource = null;
+ errorMessage = "Unexpected error ..."; //$NON-NLS-1$
+ lineIndex = 0;
+ return false;
+ }
+
+ cleanedSource = lua.toString(-3);
+ errorMessage = lua.toString(-2);
+ lineIndex = Math.max(lua.toInteger(-1) - 1, 0);
+
+ return errorMessage == null;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getLuaSourcePaths()
+ */
+ @Override
+ protected List<String> getLuaSourcePaths() {
+ ArrayList<String> sourcepaths = new ArrayList<String>();
+ sourcepaths.add(VALIDATOR_PATH);
+ return sourcepaths;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getLuacSourcePaths()
+ */
+ @Override
+ protected List<String> getLuacSourcePaths() {
+ return null;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#createLuaState()
+ */
+ @Override
+ protected LuaState createLuaState() {
+ LuaState l = new LuaState();
+ l.openLibs();
+ return l;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getPluginID()
+ */
+ @Override
+ protected String getPluginID() {
+ return Activator.PLUGIN_ID;
+ }
+
+ /**
+ * @see com.naef.jnlua.eclipse.AbstractLuaModule#getModuleName()
+ */
+ @Override
+ protected String getModuleName() {
+ return MODULE_NAME;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getCleanedSource()
+ */
+ @Override
+ public String getCleanedSource() {
+ return cleanedSource;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getErrorMessage()
+ */
+ @Override
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ /**
+ * @see org.eclipse.ldt.core.grammar.ILuaSourceValidator#getLineIndex()
+ */
+ @Override
+ public int getLineIndex() {
+ return lineIndex;
+ }
+
+}
diff --git a/plugins/org.eclipse.ldt.ui/OSGI-INF/l10n/bundle.properties b/plugins/org.eclipse.ldt.ui/OSGI-INF/l10n/bundle.properties
index 41bca8f..3258fcd 100644
--- a/plugins/org.eclipse.ldt.ui/OSGI-INF/l10n/bundle.properties
+++ b/plugins/org.eclipse.ldt.ui/OSGI-INF/l10n/bundle.properties
@@ -50,4 +50,6 @@
decorator.label.doclua = Decorator for doclua files.
rename.command.label = Rename a variable
-command.converttoluaproject.name = Convert to Lua project ...
\ No newline at end of file
+command.converttoluaproject.name = Convert to Lua project ...
+preference.page.name.grammars = Grammars
+property.page.name.grammar = Grammar
diff --git a/plugins/org.eclipse.ldt.ui/icons/obj16/grammar.png b/plugins/org.eclipse.ldt.ui/icons/obj16/grammar.png
new file mode 100644
index 0000000..c3d1e9b
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/icons/obj16/grammar.png
Binary files differ
diff --git a/plugins/org.eclipse.ldt.ui/plugin.xml b/plugins/org.eclipse.ldt.ui/plugin.xml
index 7c41c20..f829973 100644
--- a/plugins/org.eclipse.ldt.ui/plugin.xml
+++ b/plugins/org.eclipse.ldt.ui/plugin.xml
@@ -35,6 +35,12 @@
class="org.eclipse.ldt.ui.internal.preferences.LuaTodoTaskPreferencePage"
id="org.eclipse.ldt.ui.todo"
name="%preference.page.name.todotasks"/>
+ <page
+ category="org.eclipse.ldt.ui.globalpreferencepage"
+ class="org.eclipse.ldt.ui.internal.preferences.LuaGrammarPreferencePage"
+ id="org.eclipse.ldt.ui.grammarpreferencepage"
+ name="%preference.page.name.grammars">
+ </page>
</extension>
<extension
point="org.eclipse.ui.ide.projectNatureImages">
@@ -92,6 +98,21 @@
</adapt>
</enabledWhen>
</page>
+ <page
+ category="org.eclipse.ldt.ui.lua.page"
+ class="org.eclipse.ldt.ui.internal.properties.GrammarPropertyPage"
+ id="org.eclipse.ldt.ui.lua.grammar"
+ name="%property.page.name.grammar">
+ <enabledWhen>
+ <adapt
+ type="org.eclipse.core.resources.IProject">
+ <test
+ property="org.eclipse.core.resources.projectNature"
+ value="org.eclipse.ldt.nature">
+ </test>
+ </adapt>
+ </enabledWhen>
+ </page>
</extension>
<extension
point="org.eclipse.dltk.ui.buildpathContainerPage">
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/Activator.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/Activator.java
index e6e15e0..b85fd3e 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/Activator.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/Activator.java
@@ -103,6 +103,8 @@
reg.put(ImageConstants.DOCLUA_OVERLAY, AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ImageConstants.DOCLUA_OVERLAY));
reg.put(ImageConstants.DOCLUA_FILE_WIZARD_BAN, AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ImageConstants.DOCLUA_FILE_WIZARD_BAN));
+
+ reg.put(ImageConstants.GRAMMAR_OBJ16, AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, ImageConstants.GRAMMAR_OBJ16));
}
/**
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/ImageConstants.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/ImageConstants.java
index 9b70e3a..b8c7839 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/ImageConstants.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/ImageConstants.java
@@ -34,4 +34,6 @@
String DOCLUA_OVERLAY = "icons/ovr16/doclua.png"; //$NON-NLS-1$
String DOCLUA_FILE_WIZARD_BAN = "icons/wizban/doclua_newfile_wiz.png"; //$NON-NLS-1$
+
+ String GRAMMAR_OBJ16 = "icons/obj16/grammar.png"; //$NON-NLS-1$
}
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/editor/text/LuaCodeScanner.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/editor/text/LuaCodeScanner.java
index f8daa55..8e71f22 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/editor/text/LuaCodeScanner.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/editor/text/LuaCodeScanner.java
@@ -14,6 +14,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.dltk.ui.text.AbstractScriptScanner;
import org.eclipse.dltk.ui.text.IColorManager;
import org.eclipse.jface.preference.IPreferenceStore;
@@ -26,13 +27,14 @@
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.jface.text.rules.WordRule;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ldt.core.grammar.IGrammar;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
+import org.eclipse.ldt.core.internal.grammar.LuaGrammarManager;
+import org.eclipse.ldt.ui.internal.Activator;
public class LuaCodeScanner extends AbstractScriptScanner {
- @SuppressWarnings("nls")
- private static String[] fgKeywords = { "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil",
- "not", "or", "repeat", "return", "then", "true", "until", "while" };
-
private static String[] fgTokenProperties = new String[] { ILuaColorConstants.LUA_NUMBER, ILuaColorConstants.LUA_DEFAULT,
ILuaColorConstants.LUA_KEYWORD };
@@ -54,10 +56,28 @@
// Add generic whitespace rule.
rules.add(new WhitespaceRule(new LuaWhitespaceDetector()));
- // Add word rule for keywords.
+ // Get grammarName
+ String grammarName = getPreferenceStore().getString(PreferenceInitializer.GRAMMAR_DEFAULT_ID);
+ if (grammarName == null || grammarName.isEmpty())
+ grammarName = PreferenceInitializer.GRAMMAR_DEFAULT_ID_VALUE;
+
+ // Get grammar
+ IGrammar grammar = null;
+ try {
+ grammar = LuaGrammarManager.getAvailableGrammar(grammarName);
+ if (grammar == null) {
+ Activator.logWarning(String.format("Unable to find grammar for %s", grammarName)); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ Activator.logWarning(String.format("Unable to find grammar for %s", grammarName), e); //$NON-NLS-1$
+ }
+
+ // Add word rule for each keywords of grammar
final WordRule wordRule = new WordRule(new LuaWordDetector(), other);
- for (int i = 0; i < fgKeywords.length; i++) {
- wordRule.addWord(fgKeywords[i], keyword);
+ if (grammar != null) {
+ for (String word : grammar.getKeywords()) {
+ wordRule.addWord(word, keyword);
+ }
}
rules.add(wordRule);
@@ -71,6 +91,26 @@
}
/**
+ * @see org.eclipse.dltk.ui.text.AbstractScriptScanner#affectsBehavior(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ @Override
+ public boolean affectsBehavior(PropertyChangeEvent event) {
+ return PreferenceInitializer.GRAMMAR_DEFAULT_ID.equals(event.getProperty()) || super.affectsBehavior(event);
+ }
+
+ /**
+ * @see org.eclipse.dltk.ui.text.AbstractScriptScanner#adaptToPreferenceChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ @Override
+ public void adaptToPreferenceChange(PropertyChangeEvent event) {
+ if (PreferenceInitializer.GRAMMAR_DEFAULT_ID.equals(event.getProperty())) {
+ initialize();
+ } else {
+ super.adaptToPreferenceChange(event);
+ }
+ }
+
+ /**
* Indicates if argument is a white space
*
* @param char Tested character
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarContentProvider.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarContentProvider.java
new file mode 100644
index 0000000..b5be807
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarContentProvider.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.ui.internal.grammar;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+public class GrammarContentProvider implements ITreeContentProvider {
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (inputElement instanceof List<?>) {
+ Object[] array = ((List<?>) inputElement).toArray();
+ Arrays.sort(array);
+ return array;
+ }
+ return null;
+ }
+
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ return null;
+ }
+
+ @Override
+ public Object getParent(Object element) {
+ return null;
+ }
+
+ @Override
+ public boolean hasChildren(Object element) {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarLabelProvider.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarLabelProvider.java
new file mode 100644
index 0000000..0614055
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/grammar/GrammarLabelProvider.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.ui.internal.grammar;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.ldt.ui.internal.Activator;
+import org.eclipse.ldt.ui.internal.ImageConstants;
+import org.eclipse.swt.graphics.Image;
+
+public class GrammarLabelProvider implements ILabelProvider {
+
+ @Override
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ @Override
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return Activator.getDefault().getImageRegistry().get(ImageConstants.GRAMMAR_OBJ16);
+ }
+
+ @Override
+ public String getText(Object element) {
+ if (element != null) {
+ return element.toString();
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/LuaGrammarPreferencePage.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/LuaGrammarPreferencePage.java
new file mode 100644
index 0000000..221c55d
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/LuaGrammarPreferencePage.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2012 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.ldt.ui.internal.preferences;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.ldt.core.internal.LuaLanguageToolkit;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
+import org.eclipse.ldt.core.internal.grammar.LuaGrammarManager;
+import org.eclipse.ldt.ui.internal.grammar.GrammarContentProvider;
+import org.eclipse.ldt.ui.internal.grammar.GrammarLabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+
+public class LuaGrammarPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ private CheckboxTreeViewer eeTreeViewer;
+
+ protected String getHelpId() {
+ return null;
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ setDescription(Messages.LuaGrammarPreferencePage_page_description);
+ noDefaultAndApplyButton();
+ setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE, LuaLanguageToolkit.getDefault().getPreferenceQualifier()));
+ }
+
+ /**
+ * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ // ----------------
+ // CREATE CONTROL
+ // create container composite
+ Composite containerComposite = new Composite(parent, SWT.NONE);
+ GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(2).applyTo(containerComposite);
+
+ eeTreeViewer = new CheckboxTreeViewer(containerComposite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ eeTreeViewer.setContentProvider(new GrammarContentProvider());
+ eeTreeViewer.setLabelProvider(new GrammarLabelProvider());
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(eeTreeViewer.getControl());
+
+ // add a listener to allow only one default EE
+ eeTreeViewer.addCheckStateListener(new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ String grammar = (String) event.getElement();
+ if (event.getChecked()) {
+ // allow to check only one element of the table
+ eeTreeViewer.setCheckedElements(new Object[] { grammar });
+ getPreferenceStore().setValue(PreferenceInitializer.GRAMMAR_DEFAULT_ID, grammar);
+ } else {
+ // removing the default ee from pref
+ getPreferenceStore().setValue(PreferenceInitializer.GRAMMAR_DEFAULT_ID, "none"); //$NON-NLS-1$
+ }
+ validateGrammar();
+ }
+ });
+
+ // ----------------
+ // Initialize UI
+ initializePage();
+ return containerComposite;
+ }
+
+ private void initializePage() {
+ if (eeTreeViewer == null || eeTreeViewer.getControl().isDisposed())
+ return;
+
+ // Refresh list
+ List<String> availableGrammars = LuaGrammarManager.getAvailableGrammars();
+ eeTreeViewer.setInput(availableGrammars);
+
+ // Set default interpreter
+ String defaultGrammar = getPreferenceStore().getString(PreferenceInitializer.GRAMMAR_DEFAULT_ID);
+ for (String grammar : availableGrammars) {
+ eeTreeViewer.setChecked(grammar, grammar.equals(defaultGrammar));
+ }
+ }
+
+ public void validateGrammar() {
+ if (eeTreeViewer.getCheckedElements().length == 0) {
+ setMessage(Messages.LuaGrammarPreferencePage_Warning_no_grammar, WARNING);
+ return;
+ }
+ setMessage(null);
+ }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/Messages.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/Messages.java
index 426489d..41b0a9f 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/Messages.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/Messages.java
@@ -43,6 +43,8 @@
public static String LuaFormatterModifyDialogIndentation;
public static String LuaFoldingPreferencePage_initiallyFoldLevelOneBlocks;
public static String LuaFoldingPreferencePage_initiallyFoldDoc;
+ public static String LuaGrammarPreferencePage_page_description;
+ public static String LuaGrammarPreferencePage_Warning_no_grammar;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/messages.properties b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/messages.properties
index 79a4eed..6f757e7 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/messages.properties
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/preferences/messages.properties
@@ -35,4 +35,6 @@
LuaFormatterModifyDialogIndentation=Indentation
LuaFormatterIndentationTabPageTableIndentationPolicy=Table indentation policy
LuaFoldingPreferencePage_initiallyFoldLevelOneBlocks=Blocks
-LuaFoldingPreferencePage_initiallyFoldDoc=LuaDocumentor Comments
\ No newline at end of file
+LuaFoldingPreferencePage_initiallyFoldDoc=LuaDocumentor Comments
+LuaGrammarPreferencePage_page_description=Select the default Lua grammar :
+LuaGrammarPreferencePage_Warning_no_grammar=No default Grammar.
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/GrammarPropertyPage.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/GrammarPropertyPage.java
new file mode 100644
index 0000000..21e512a
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/GrammarPropertyPage.java
@@ -0,0 +1,133 @@
+package org.eclipse.ldt.ui.internal.properties;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.dltk.core.SourceParserUtil;
+import org.eclipse.dltk.internal.ui.util.CoreUtility;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ldt.core.internal.LuaLanguageToolkit;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
+import org.eclipse.ldt.core.internal.grammar.LuaGrammarManager;
+import org.eclipse.ldt.ui.internal.grammar.GrammarContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbenchPropertyPage;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+
+public class GrammarPropertyPage extends PropertyPage implements IWorkbenchPropertyPage {
+
+ private ComboViewer availableGrammarComboViewer;
+ private IProject project;
+
+ public GrammarPropertyPage() {
+ }
+
+ /**
+ * Initializes a ProjectReferencePage.
+ */
+ private void initialize() {
+ project = (IProject) getElement().getAdapter(IResource.class);
+ noDefaultAndApplyButton();
+ setDescription(Messages.GrammarPropertyPage_page_description);
+ if (project != null)
+ setPreferenceStore(new ScopedPreferenceStore(new ProjectScope(project), LuaLanguageToolkit.getDefault().getPreferenceQualifier()));
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+ // Initialize class
+ initialize();
+
+ // ----------------
+ // CREATE CONTROL
+ // Create container composite
+ Composite containerComposite = new Composite(parent, SWT.NONE);
+ GridLayoutFactory.swtDefaults().margins(0, 0).numColumns(1).applyTo(containerComposite);
+ createDescriptionLabel(containerComposite);
+
+ // Grammar combo viewer
+ availableGrammarComboViewer = new ComboViewer(containerComposite, SWT.READ_ONLY | SWT.BORDER);
+ availableGrammarComboViewer.setContentProvider(new GrammarContentProvider());
+ GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).grab(true, false).applyTo(availableGrammarComboViewer.getControl());
+
+ // ----------------
+ // Initialize UI component
+ initializePage();
+ return containerComposite;
+ }
+
+ private void initializePage() {
+ if (availableGrammarComboViewer == null || availableGrammarComboViewer.getControl().isDisposed() || getPreferenceStore() == null)
+ return;
+
+ // Refresh list
+ List<String> availableGrammars = LuaGrammarManager.getAvailableGrammars();
+ availableGrammarComboViewer.setInput(availableGrammars);
+
+ // Set default interpreter
+ String defaultGrammar = getPreferenceStore().getString(PreferenceInitializer.GRAMMAR_DEFAULT_ID);
+ availableGrammarComboViewer.setSelection(new StructuredSelection(defaultGrammar));
+ }
+
+ public String getSelectedGrammar() {
+ ISelection selection = availableGrammarComboViewer.getSelection();
+ if (selection instanceof IStructuredSelection) {
+ Object firstElement = ((IStructuredSelection) selection).getFirstElement();
+ if (firstElement instanceof String)
+ return (String) firstElement;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean performOk() {
+ // Get current values
+ String oldGrammar = getPreferenceStore().getString(PreferenceInitializer.GRAMMAR_DEFAULT_ID);
+ String newGrammar = getSelectedGrammar();
+
+ // Change preference
+ getPreferenceStore().setValue(PreferenceInitializer.GRAMMAR_DEFAULT_ID, newGrammar);
+
+ // Get workbench Container
+ IWorkbenchPreferenceContainer container = null;
+ if (getContainer() instanceof IWorkbenchPreferenceContainer)
+ container = (IWorkbenchPreferenceContainer) getContainer();
+
+ // rebuild project if needed
+ boolean needsBuild = oldGrammar != null && !oldGrammar.equals(newGrammar) && container != null;
+ boolean doBuild = false;
+ if (needsBuild) {
+ MessageDialog dialog = new MessageDialog(getShell(), Messages.GrammarPropertyPage_rebuild_dialog_title, null,
+ Messages.GrammarPropertyPage_rebuild_dialog_message, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 2);
+ int res = dialog.open();
+ if (res == 0) {
+ doBuild = true;
+ } else if (res != 1) {
+ return false; // cancel pressed
+ }
+ }
+
+ if (doBuild) { // post build
+ Job job = CoreUtility.getBuildJob(project);
+ // TODO we should not clear all the cache, but just the project one.
+ SourceParserUtil.clearCache();
+ container.registerUpdateJob(job);
+ }
+ return super.performOk();
+ }
+}
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/Messages.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/Messages.java
new file mode 100644
index 0000000..06badd0
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/Messages.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.ui.internal.properties;
+
+import org.eclipse.osgi.util.NLS;
+
+// CHECKSTYLE NLS: OFF
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.ldt.ui.internal.properties.messages"; //$NON-NLS-1$
+ public static String GrammarPropertyPage_page_description;
+ public static String GrammarPropertyPage_rebuild_dialog_message;
+ public static String GrammarPropertyPage_rebuild_dialog_title;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
+// CHECKSTYLE NLS: ON
\ No newline at end of file
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/messages.properties b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/messages.properties
new file mode 100644
index 0000000..92cbf57
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/internal/properties/messages.properties
@@ -0,0 +1,3 @@
+GrammarPropertyPage_page_description=Define the grammar to use for code validation and keyword highlight :
+GrammarPropertyPage_rebuild_dialog_message=A grammar settings have changed. A rebuild of the project is required for changes to take effect. Build the project now ?
+GrammarPropertyPage_rebuild_dialog_title=Grammar Settings Changed
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/LuaProjectCreator.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/LuaProjectCreator.java
index 1de7b7d..a7e4e61 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/LuaProjectCreator.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/LuaProjectCreator.java
@@ -23,10 +23,12 @@
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.ui.wizards.ILocationGroup;
@@ -35,9 +37,12 @@
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.ldt.core.LuaConstants;
import org.eclipse.ldt.core.buildpath.LuaExecutionEnvironment;
+import org.eclipse.ldt.core.internal.LuaLanguageToolkit;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
import org.eclipse.ldt.core.internal.buildpath.LuaExecutionEnvironmentBuildpathUtil;
import org.eclipse.ldt.ui.internal.Activator;
import org.eclipse.ldt.ui.wizards.pages.LuaProjectSettingsPage;
+import org.osgi.service.prefs.BackingStoreException;
public class LuaProjectCreator extends ProjectCreator {
@@ -58,6 +63,10 @@
ProjectCreateStep createSourceFolderStep = createSourceFolderStep();
if (createSourceFolderStep != null)
addStep(IProjectCreateStep.KIND_FINISH, 0, createSourceFolderStep, (IWizardPage) locationGroup);
+
+ ProjectCreateStep setGrammarStep = createGrammarStep();
+ if (setGrammarStep != null)
+ addStep(IProjectCreateStep.KIND_FINISH, 0, setGrammarStep, (IWizardPage) locationGroup);
}
/**
@@ -123,6 +132,23 @@
return entries.toArray(new IBuildpathEntry[entries.size()]);
}
+ private class SetGrammarStep extends ProjectCreateStep {
+
+ @Override
+ public void execute(IProject project, IProgressMonitor monitor) throws CoreException, InterruptedException {
+ String grammar = luaProjectSettingPage.getGrammar();
+ try {
+ IEclipsePreferences node = new ProjectScope(project).getNode(LuaLanguageToolkit.getDefault().getPreferenceQualifier());
+ node.put(PreferenceInitializer.GRAMMAR_DEFAULT_ID, grammar);
+ node.flush();
+ } catch (BackingStoreException e) {
+ Activator.logError(MessageFormat.format("Unable store grammar version {0} for project {1}", grammar, project.getName()), e); //$NON-NLS-1$
+ }
+ monitor.done();
+ }
+
+ }
+
/**
* Creates a default file named LuaWizardContants.DEFAULT_MAIN_FILE in default source folder.
*/
@@ -200,4 +226,8 @@
protected ProjectCreateStep createSourceFolderStep() {
return new CreateDefaultSourceFolderProjectCreateStep();
}
+
+ protected ProjectCreateStep createGrammarStep() {
+ return new SetGrammarStep();
+ }
}
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/GrammarGroup.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/GrammarGroup.java
new file mode 100644
index 0000000..4e927c3
--- /dev/null
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/GrammarGroup.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.ui.wizards.pages;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.ldt.core.internal.LuaLanguageToolkit;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
+import org.eclipse.ldt.core.internal.grammar.LuaGrammarManager;
+import org.eclipse.ldt.ui.internal.grammar.GrammarContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+
+public class GrammarGroup {
+
+ private ComboViewer availableGrammarComboViewer;
+ private ISelection selection;
+
+ public GrammarGroup(final Composite parent) {
+ // Create group
+ final Group group = new Group(parent, SWT.NONE);
+ group.setText(Messages.GrammarGroup_group_name);
+ GridDataFactory.swtDefaults().align(SWT.FILL, SWT.CENTER).applyTo(group);
+ GridLayoutFactory.swtDefaults().numColumns(1).applyTo(group);
+
+ // Grammar combo viewer
+ availableGrammarComboViewer = new ComboViewer(group, SWT.READ_ONLY | SWT.BORDER);
+ availableGrammarComboViewer.setContentProvider(new GrammarContentProvider());
+ GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).grab(true, false).applyTo(availableGrammarComboViewer.getControl());
+
+ initializeGroup();
+ }
+
+ public String getSelectedGrammar() {
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ if (availableGrammarComboViewer != null) {
+ selection = availableGrammarComboViewer.getSelection();
+ } else {
+ selection = null;
+ }
+ }
+ });
+
+ if (selection instanceof IStructuredSelection) {
+ Object firstElement = ((IStructuredSelection) selection).getFirstElement();
+ if (firstElement instanceof String)
+ return (String) firstElement;
+ }
+
+ return null;
+ }
+
+ private void initializeGroup() {
+ if (availableGrammarComboViewer == null || availableGrammarComboViewer.getControl().isDisposed())
+ return;
+
+ // Refresh list
+ List<String> availableGrammars = LuaGrammarManager.getAvailableGrammars();
+ availableGrammarComboViewer.setInput(availableGrammars);
+
+ // Set default interpreter
+ ScopedPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, LuaLanguageToolkit.getDefault()
+ .getPreferenceQualifier());
+ String defaultGrammar = preferenceStore.getString(PreferenceInitializer.GRAMMAR_DEFAULT_ID);
+ if (defaultGrammar != null)
+ availableGrammarComboViewer.setSelection(new StructuredSelection(defaultGrammar));
+ }
+}
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/LuaProjectSettingsPage.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/LuaProjectSettingsPage.java
index 5632082..88c8351 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/LuaProjectSettingsPage.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/LuaProjectSettingsPage.java
@@ -27,6 +27,7 @@
public class LuaProjectSettingsPage extends ProjectWizardFirstPage implements Observer {
private LuaExecutionEnvironmentGroup luaExecutionEnvironmentGroup;
+ private GrammarGroup grammarGroup;
public LuaProjectSettingsPage() {
setTitle(Messages.LuaProjecSettingsPageLabel);
@@ -55,11 +56,15 @@
protected void createCustomGroups(final Composite composite) {
luaExecutionEnvironmentGroup = createExecutionEnvironmentGroup(composite);
+ grammarGroup = createGrammarGroup(composite);
+ }
+
+ protected GrammarGroup createGrammarGroup(Composite composite) {
+ return new GrammarGroup(composite);
}
protected LuaExecutionEnvironmentGroup createExecutionEnvironmentGroup(final Composite composite) {
- final LuaExecutionEnvironmentGroup eeGroup = new LuaExecutionEnvironmentGroup(composite);
- return eeGroup;
+ return new LuaExecutionEnvironmentGroup(composite);
}
/**
@@ -79,6 +84,12 @@
return null;
}
+ public String getGrammar() {
+ if (grammarGroup != null)
+ return grammarGroup.getSelectedGrammar();
+ return null;
+ }
+
/**
*
* @deprecated Use hasToCreateTemplate() instead.
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/Messages.java b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/Messages.java
index da091c6..337c966 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/Messages.java
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/Messages.java
@@ -31,6 +31,8 @@
/** @since 1.2 */
public static String DocLuaFilePage_title;
+ public static String GrammarGroup_group_name;
+
/** @since 1.1 */
public static String LuaExecutionEnvironmentGroupTemplateLabel;
diff --git a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/messages.properties b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/messages.properties
index f3452db..7565732 100644
--- a/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/messages.properties
+++ b/plugins/org.eclipse.ldt.ui/src/org/eclipse/ldt/ui/wizards/pages/messages.properties
@@ -14,6 +14,7 @@
ConvertToLuaProjectMainPage_migrationMessage=You will migrate a koneki project to new Lua project. This can not be undone.
DocLuaFilePage_description=Create a DocLua file. A DocLua file is a file describing an API to\nenable tooling, and will not be taken in account at runtime.
DocLuaFilePage_title=DocLua File
+GrammarGroup_group_name=Target Grammar
LuaExecutionEnvironmentGroupMainLabel=Create default template project ready to run.
LuaExecutionEnvironmentGroupTemplateLabel=Create default template project ready to run.
LuaExecutionEnvironmentGroupManageExecutionEnvironment=Configure Execution Environments...
diff --git a/plugins/org.eclipse.ldt/META-INF/MANIFEST.MF b/plugins/org.eclipse.ldt/META-INF/MANIFEST.MF
index 11cdbb1..118447f 100644
--- a/plugins/org.eclipse.ldt/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.ldt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.ldt;singleton:=true
-Bundle-Version: 1.2.0.qualifier
+Bundle-Version: 1.3.0.qualifier
Bundle-Activator: org.eclipse.ldt.core.internal.Activator
Bundle-Vendor: %Bundle-Vendor
Require-Bundle: org.eclipse.ui;bundle-version="3.5.0",
@@ -17,6 +17,7 @@
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.ldt.core,
org.eclipse.ldt.core.buildpath,
+ org.eclipse.ldt.core.grammar,
org.eclipse.ldt.core.internal;
x-friends:="org.eclipse.ldt.core.tests,
org.eclipse.ldt.debug.core,
@@ -67,6 +68,7 @@
org.eclipse.ldt.debug.core,
org.eclipse.ldt.debug.ui,
org.eclipse.ldt.ui",
+ org.eclipse.ldt.core.internal.grammar,
org.eclipse.ldt.core.internal.todo;
x-friends:="org.eclipse.ldt.core.tests,
org.eclipse.ldt.debug.core,
diff --git a/plugins/org.eclipse.ldt/OSGI-INF/l10n/bundle.properties b/plugins/org.eclipse.ldt/OSGI-INF/l10n/bundle.properties
index 98ec9e0..b36344c 100644
--- a/plugins/org.eclipse.ldt/OSGI-INF/l10n/bundle.properties
+++ b/plugins/org.eclipse.ldt/OSGI-INF/l10n/bundle.properties
@@ -14,3 +14,4 @@
Bundle-Name = Lua Development Tools Core
Bundle-Vendor = Eclipse LDT
extension-point.executionenvironement.name = Execution Environment
+extension-point.luagrammar.name = Lua Grammar
\ No newline at end of file
diff --git a/plugins/org.eclipse.ldt/plugin.xml b/plugins/org.eclipse.ldt/plugin.xml
index be4d33d..872d890 100644
--- a/plugins/org.eclipse.ldt/plugin.xml
+++ b/plugins/org.eclipse.ldt/plugin.xml
@@ -12,6 +12,7 @@
<plugin>
<extension-point id="executionEnvironment" name="%extension-point.executionenvironement.name" schema="schema/executionEnvironment.exsd"/>
+ <extension-point id="luaGrammar" name="%extension-point.luagrammar.name" schema="schema/luaGrammar.exsd"/>
<extension
id="nature"
name="%extension.name"
diff --git a/plugins/org.eclipse.ldt/pom.xml b/plugins/org.eclipse.ldt/pom.xml
index 5d97712..89b5dce 100644
--- a/plugins/org.eclipse.ldt/pom.xml
+++ b/plugins/org.eclipse.ldt/pom.xml
@@ -19,7 +19,7 @@
</parent>
<groupId>org.eclipse.ldt</groupId>
<artifactId>org.eclipse.ldt</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/plugins/org.eclipse.ldt/schema/luaGrammar.exsd b/plugins/org.eclipse.ldt/schema/luaGrammar.exsd
new file mode 100644
index 0000000..76dbbe9
--- /dev/null
+++ b/plugins/org.eclipse.ldt/schema/luaGrammar.exsd
@@ -0,0 +1,116 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ldt" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.ldt" id="luaGrammar" name="Lua Grammar"/>
+ </appinfo>
+ <documentation>
+ Allow to register a grammar for Lua.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="grammar"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="grammar">
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="validator" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.ldt.core.ILuaSourceValidator"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="keywords" type="string">
+ <annotation>
+ <documentation>
+ Grammar keywords separated with comma.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/plugins/org.eclipse.ldt/script/local/javamodelsbuilder.lua b/plugins/org.eclipse.ldt/script/local/javamodelsbuilder.lua
index 5953f01..b381778 100644
--- a/plugins/org.eclipse.ldt/script/local/javamodelsbuilder.lua
+++ b/plugins/org.eclipse.ldt/script/local/javamodelsbuilder.lua
@@ -25,106 +25,12 @@
-- Build Java Model from source code
--
-- @param #string source Code to parse
--- @return LuaSourceRoot, DLTK node, root of DLTK AST
-function M.build(source, modulename)
- -- create root object
- local root = javamodelfactory.newsourceroot(#source)
+-- @param LuaSourceRoot, DLTK node, root of DLTK AST
+function M.build(source, modulename, root)
-- manage shebang
if source then source = source:gsub("^(#.-\n)", function (s) return string.rep(' ',string.len(s)) end) end
- -- check for errors
- local f, err = loadstring(source,'source_to_check')
- if not f then
- local lineindex, errmessage = string.match(err,"%[string \"source_to_check\"%]:(%d+):(.*)")
- errmessage = errmessage or err
- lineindex = lineindex and tonumber(lineindex) or 1
- javamodelfactory.setproblem(root,lineindex-1 , -1, -1, -1, errmessage)
-
- -- -------------------------------------------------
- -- EXPERIMENTAL CODE : we try to remove faulty code
- -- -------------------------------------------------
- local nbline = select(2, source:gsub('\n', '\n'))+1
- if source and nbline > 1 then
- -- define function that replace all character of a given line in space characters
- local function cleanline (source, linetoclean,nbline)
- local cleanedsource
- local iscleaned = false
- if linetoclean == nbline then
- -- manage last line
- cleanedsource = source:gsub('([^\n]-)$',function (lastline)
- iscleaned = true
- return string.rep(' ',string.len(lastline))
- end)
- elseif linetoclean == 1 then
- -- manage first line
- cleanedsource = source:gsub('^(.-)\n',function (firstline)
- iscleaned = true
- return string.rep(' ',string.len(firstline)).."\n"
- end)
- elseif linetoclean > 1 then
- -- manage other case
- cleanedsource = source:gsub('^('..string.rep(".-\n",linetoclean-1)..')(.-)\n',function (start,faultyline)
- iscleaned = true
- return start..string.rep(' ',string.len(faultyline)) .. "\n"
- end)
- end
- return cleanedsource, iscleaned
- end
-
- local cleanedsource
- local iscleaned = false
- if lineindex == 1 then
- -- FIRST LINE CASE : error is on line 1, just clean this line and check for errors
- cleanedsource, iscleaned = cleanline(source,1,nbline)
- f, _ = loadstring(cleanedsource,'source_to_check')
- else
- -- OTHER CASES: first, cleaning ...
- -- if something is not closed we try to remove the line where it is opened.
- local linestart = string.match(err,"%(to close .* at line (%d+)%)")
- if linestart then
- cleanedsource, iscleaned = cleanline(source,tonumber(linestart),nbline)
- elseif lineindex > 1 then
- -- in other case, we try to remove the "real" code line before the error
- -- so, we start by finding the "real" line:
- local realcodelineindex = nil
- for i=lineindex-1,1,-1 do
- -- we go from the line just before the error to the first line, searching a "real" code line.
- -- (no empty line or single comment line, we do not manage multiline comment)
- local codeline = source:match('^'..string.rep(".-\n",i-1)..'(.-)\n')
- if codeline and not codeline:find('^%s*$') and not codeline:find('^%s*%-%-.*$') then
- realcodelineindex = i
- break
- end
- end
- if realcodelineindex then
- cleanedsource, iscleaned = cleanline(source,realcodelineindex,nbline)
- end
- end
-
- -- after cleaning, recheck hoping there are no errors.
- if iscleaned then
- f, _ = loadstring(cleanedsource,'source_to_check')
- -- if it fail, we try to remove the line in error
- if not f then
- cleanedsource = cleanline(source,lineindex,nbline)
- f, _ = loadstring(cleanedsource,'source_to_check')
- end
- end
- end
-
- -- take cleaned source as source
- if f then
- source = cleanedsource
- end
- end
- -- ------------------------------------------------
- -- END OF EXPERIMENTAL CODE
- -- -------------------------------------------------
- end
-
- if not f then return root end
-
-- if no errors, check AST
local ast = mlc:src_to_ast( source )
@@ -152,7 +58,6 @@
-- TODO clean perf profiling
-- local e = os.clock()
-- print ('global time', type(e), type(s),(e*1000-s*1000))
- return root
end
return M
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/IGrammar.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/IGrammar.java
new file mode 100644
index 0000000..dfa8cba
--- /dev/null
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/IGrammar.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.core.grammar;
+
+import java.util.List;
+
+public interface IGrammar {
+
+ String getName();
+
+ ILuaSourceValidator getValidator();
+
+ List<String> getKeywords();
+
+}
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/ILuaSourceValidator.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/ILuaSourceValidator.java
new file mode 100644
index 0000000..eb74e63
--- /dev/null
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/grammar/ILuaSourceValidator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.core.grammar;
+
+
+public interface ILuaSourceValidator {
+
+ boolean valid(String source);
+
+ String getCleanedSource();
+
+ String getErrorMessage();
+
+ int getLineIndex();
+}
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/PreferenceInitializer.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/PreferenceInitializer.java
index 93dc228..5c1f98a 100644
--- a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/PreferenceInitializer.java
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/PreferenceInitializer.java
@@ -17,6 +17,9 @@
public class PreferenceInitializer extends AbstractPreferenceInitializer {
public static final String EE_DEFAULT_ID = "EE__default_id"; //$NON-NLS-1$
+ public static final String EE_DEFAULT_ID_VALUE = "lua-5.1"; //$NON-NLS-1$
+ public static final String GRAMMAR_DEFAULT_ID = "Grammar__default_id"; //$NON-NLS-1$
+ public static final String GRAMMAR_DEFAULT_ID_VALUE = "lua-5.1"; //$NON-NLS-1$
public static final String USE_GLOBAL_VAR_IN_LDT = "USE_GLOBAL_VAR_IN_LDT"; //$NON-NLS-1$
@Override
@@ -24,7 +27,8 @@
ScopedPreferenceStore preferenceStore = new ScopedPreferenceStore(DefaultScope.INSTANCE, LuaLanguageToolkit.getDefault()
.getPreferenceQualifier());
- preferenceStore.setDefault(EE_DEFAULT_ID, "lua-5.1"); //$NON-NLS-1$
+ preferenceStore.setDefault(EE_DEFAULT_ID, EE_DEFAULT_ID_VALUE);
+ preferenceStore.setDefault(GRAMMAR_DEFAULT_ID, GRAMMAR_DEFAULT_ID_VALUE);
preferenceStore.setDefault(USE_GLOBAL_VAR_IN_LDT, true);
}
}
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/LuaSourceParser.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/LuaSourceParser.java
index 04a69c1..8d51b2b 100644
--- a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/LuaSourceParser.java
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/LuaSourceParser.java
@@ -14,6 +14,12 @@
import java.util.Hashtable;
import java.util.Map;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.parser.AbstractSourceParser;
import org.eclipse.dltk.ast.parser.IModuleDeclaration;
@@ -25,14 +31,20 @@
import org.eclipse.dltk.core.IElementChangedListener;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IModelElementDelta;
+import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.ldt.core.LuaUtils;
+import org.eclipse.ldt.core.grammar.IGrammar;
+import org.eclipse.ldt.core.grammar.ILuaSourceValidator;
import org.eclipse.ldt.core.internal.Activator;
+import org.eclipse.ldt.core.internal.LuaLanguageToolkit;
+import org.eclipse.ldt.core.internal.PreferenceInitializer;
import org.eclipse.ldt.core.internal.ast.models.LuaDLTKModelUtils;
import org.eclipse.ldt.core.internal.ast.models.api.LuaFileAPI;
import org.eclipse.ldt.core.internal.ast.models.common.LuaSourceRoot;
import org.eclipse.ldt.core.internal.ast.models.file.LuaInternalContent;
+import org.eclipse.ldt.core.internal.grammar.LuaGrammarManager;
import org.eclipse.osgi.util.NLS;
/**
@@ -110,31 +122,41 @@
synchronized (LuaSourceParser.class) {
try {
- // remove Byte Order Mark :
+ // Remove Byte Order Mark :
if (source.startsWith("\ufeff")) { //$NON-NLS-1$
source = source.substring(1);
}
- // Build AST
- module = astBuilder.buildAST(source, moduleName);
+ // Valid source code
+ ILuaSourceValidator sourceValidator = getValidator(getProject(input));
+ if (sourceValidator == null) {
+ Activator.logWarning(NLS.bind("No validator found for input {0}.", input.getFileName())); //$NON-NLS-1$
+ module.setProblem(1, 1, 0, 0, "No validator have have been found for this file."); //$NON-NLS-1$
+ } else {
+ boolean valid = sourceValidator.valid(source);
+ String cleanedSource = sourceValidator.getCleanedSource();
+ if (!valid)
+ module.setProblem(sourceValidator.getLineIndex(), -1, -1, -1, sourceValidator.getErrorMessage());
- // Fix AST
- if (module != null)
+ // Build AST
+ if (cleanedSource != null)
+ astBuilder.buildAST(cleanedSource, moduleName, module);
+
+ // Fix AST
module.traverse(new EncodingVisitor(fixer));
+ }
}
// CHECKSTYLE:OFF
catch (final Exception e) {
// CHECKSTYLE:ON
Activator.logWarning(NLS.bind("Unable to parse file {0}.", input.getFileName()), e); //$NON-NLS-1$
// the module is probably on error.
- if (module == null)
- module = new LuaSourceRoot(source.length());
module.setProblem(1, 1, 0, 0, "This file probably contains a syntax error."); //$NON-NLS-1$
}
// Deal with errors on Lua side
if (module != null) {
- // if module contains a syntax error
+ // If module contains a syntax error
if (module.hasError()) {
// add error to reporter
final DefaultProblem problem = module.getProblem();
@@ -182,4 +204,35 @@
}
return module;
}
+
+ private ILuaSourceValidator getValidator(IProject project) throws CoreException {
+ // Create context
+ IScopeContext[] context;
+ if (project != null)
+ context = new IScopeContext[] { new ProjectScope(project), InstanceScope.INSTANCE };
+ else
+ context = new IScopeContext[] { InstanceScope.INSTANCE };
+
+ // Get grammarName
+ String grammarName = Platform.getPreferencesService().getString(LuaLanguageToolkit.getDefault().getPreferenceQualifier(),
+ PreferenceInitializer.GRAMMAR_DEFAULT_ID, PreferenceInitializer.GRAMMAR_DEFAULT_ID_VALUE, context);
+
+ // Get grammar
+ IGrammar grammar = LuaGrammarManager.getAvailableGrammar(grammarName);
+ if (grammar != null)
+ return grammar.getValidator();
+ return null;
+ }
+
+ private IProject getProject(IModuleSource input) {
+ if (input == null)
+ return null;
+ IModelElement modelElement = input.getModelElement();
+ if (modelElement == null)
+ return null;
+ IScriptProject scriptProject = modelElement.getScriptProject();
+ if (scriptProject == null)
+ return null;
+ return scriptProject.getProject();
+ }
}
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/ModelsBuilderLuaModule.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/ModelsBuilderLuaModule.java
index 74dae28..d3ac6ef 100644
--- a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/ModelsBuilderLuaModule.java
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/ast/parser/ModelsBuilderLuaModule.java
@@ -34,7 +34,7 @@
private LuaState lua = null;
- public synchronized LuaSourceRoot buildAST(final String source, final String modulename) {
+ public synchronized void buildAST(final String source, final String modulename, final LuaSourceRoot root) {
if (lua == null)
lua = loadLuaModule();
@@ -42,13 +42,11 @@
lua.getField(-1, "build"); //$NON-NLS-1$
lua.pushString(source);
lua.pushString(modulename);
- lua.call(2, 1);
- LuaSourceRoot luaSourceRoot = lua.checkJavaObject(-1, LuaSourceRoot.class);
- lua.pop(2);
+ lua.pushJavaObject(root);
+ lua.call(3, 0);
+ lua.pop(1);
// lua.close();
-
- return luaSourceRoot;
}
/**
diff --git a/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/grammar/LuaGrammarManager.java b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/grammar/LuaGrammarManager.java
new file mode 100644
index 0000000..1e1f5be
--- /dev/null
+++ b/plugins/org.eclipse.ldt/src/org/eclipse/ldt/core/internal/grammar/LuaGrammarManager.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Sierra Wireless 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:
+ * Sierra Wireless - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ldt.core.internal.grammar;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.ldt.core.grammar.IGrammar;
+import org.eclipse.ldt.core.grammar.ILuaSourceValidator;
+
+public final class LuaGrammarManager {
+
+ private static final String EXTENSION_POINT_ID = "org.eclipse.ldt.luaGrammar"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_VALIDATOR = "validator"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_KEYWORDS = "keywords"; //$NON-NLS-1$
+ private static final String KEYWORDS_SEPARATOR = ","; //$NON-NLS-1$
+
+ private LuaGrammarManager() {
+ }
+
+ private static IConfigurationElement getGrammarContribution(String name) throws CoreException {
+ if (name == null)
+ return null;
+
+ // search plug-in contribution
+ IConfigurationElement[] contributions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID);
+ for (int i = 0; i < contributions.length; i++) {
+ String nameAttribute = contributions[i].getAttribute(ATTRIBUTE_NAME);
+
+ if (name.equals(nameAttribute)) {
+ return contributions[i];
+ }
+ }
+ return null;
+ }
+
+ private static IGrammar getGrammarFromContribution(final String name) throws CoreException {
+ // search plug-in contribution
+ IConfigurationElement grammarContribution = getGrammarContribution(name);
+ if (grammarContribution != null) {
+
+ final ILuaSourceValidator validator = (ILuaSourceValidator) grammarContribution.createExecutableExtension(ATTRIBUTE_VALIDATOR);
+
+ final String keywordsAttribute = grammarContribution.getAttribute(ATTRIBUTE_KEYWORDS);
+ final List<String> keywords = new ArrayList<String>();
+ if (keywordsAttribute != null) {
+ for (String word : keywordsAttribute.split(KEYWORDS_SEPARATOR)) {
+ // TODO validate the keyword ? no special char, ...
+ String cleanWord = word.trim();
+ if (!cleanWord.isEmpty())
+ keywords.add(cleanWord);
+ }
+ }
+
+ return new IGrammar() {
+
+ @Override
+ public ILuaSourceValidator getValidator() {
+ return validator;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public List<String> getKeywords() {
+ return keywords;
+ }
+ };
+ }
+ return null;
+ }
+
+ public static IGrammar getAvailableGrammar(String name) throws CoreException {
+ return getGrammarFromContribution(name);
+ }
+
+ public static List<String> getAvailableGrammars() {
+ List<String> grammars = new ArrayList<String>();
+
+ // search plug-in contribution
+ IConfigurationElement[] contributions = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID);
+ for (int i = 0; i < contributions.length; i++) {
+ String nameAttribute = contributions[i].getAttribute(ATTRIBUTE_NAME);
+
+ if (nameAttribute != null && !nameAttribute.isEmpty()) {
+ grammars.add(nameAttribute);
+ }
+ }
+
+ return grammars;
+ }
+}
diff --git a/tests/org.eclipse.ldt.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.ldt.core.tests/META-INF/MANIFEST.MF
index 3abe6e3..d8300c8 100644
--- a/tests/org.eclipse.ldt.core.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.ldt.core.tests/META-INF/MANIFEST.MF
@@ -9,7 +9,8 @@
org.junit;bundle-version="4.5.0",
org.eclipse.core.resources;bundle-version="3.6.0",
org.eclipse.dltk.core;bundle-version="[5.0.0,6.0.0)",
- org.eclipse.ldt;bundle-version="0.9.0"
+ org.eclipse.ldt;bundle-version="0.9.0",
+ org.eclipse.ldt.support.lua51;bundle-version="1.1.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.ldt.core.tests,
diff --git a/tests/org.eclipse.ldt.lua.tests/tests/formatter/input/basic/longstring2.lua b/tests/org.eclipse.ldt.lua.tests/tests/formatter/input/basic/longstring2.lua
index 4272aa7..6c06fed 100644
--- a/tests/org.eclipse.ldt.lua.tests/tests/formatter/input/basic/longstring2.lua
+++ b/tests/org.eclipse.ldt.lua.tests/tests/formatter/input/basic/longstring2.lua
@@ -4,4 +4,4 @@
local longString = [=[Long string
4 space at the start of this line
4 space at the end of this line
-]=]
+]=]
\ No newline at end of file
diff --git a/tests/org.eclipse.ldt.metalua.tests/src/org/eclipse/ldt/metalua/tests/internal/cases/TestMetalua.java b/tests/org.eclipse.ldt.metalua.tests/src/org/eclipse/ldt/metalua/tests/internal/cases/TestMetalua.java
index e61ff9f..d04762a 100644
--- a/tests/org.eclipse.ldt.metalua.tests/src/org/eclipse/ldt/metalua/tests/internal/cases/TestMetalua.java
+++ b/tests/org.eclipse.ldt.metalua.tests/src/org/eclipse/ldt/metalua/tests/internal/cases/TestMetalua.java
@@ -138,6 +138,18 @@
}
}
+ /** Run from source */
+ public void testlua52() {
+ try {
+ final StringBuffer sb = new StringBuffer("local mlc = require ('metalua.compiler').new()\n"); //$NON-NLS-1$
+ sb.append("ast = mlc:src_to_ast[[goto a\nprint 'hello'\n::a::]]"); //$NON-NLS-1$
+ state.load(sb.toString(), "metaluaCode"); //$NON-NLS-1$
+ state.call(0, 0);
+ } catch (LuaException e) {
+ fail(e.getMessage());
+ }
+ }
+
public void testSourcesPath() {
String path = Metalua.path();
assertFalse("Metalua sources path is not definded.", path.isEmpty());//$NON-NLS-1$