Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Languages: added Rust [WIP] #3419

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/chrome/komodo/content/pref/pref-syntax-checking.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,23 @@ function javaScriptInfo(languageName) {
};
}

languageInfo.Rust = {
browseForRustcBinary: () => {
let rustc_binary = document.getElementById('rust.linter.binaries.rustc');
let currentPath = rustc_binary.value;
let path = ko.filepicker.browseForExeFile(null, currentPath || "");
if (path)
rustc_binary.value = path;
},
browseForCargoBinary: () => {
let cargo_config = document.getElementById('rust.linter.binaries.cargo');
let currentPath = cargo_config.value;
let path = ko.filepicker.browseForExeFile(null, currentPath || "");
if (path)
cargo_config.value = path;
}
};

function typescript_setup() {
if (!('TypeScript' in dialog)) {
dialog.TypeScript = {};
Expand Down
39 changes: 39 additions & 0 deletions src/chrome/komodo/content/pref/pref-syntax-checking.xul
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,45 @@
</groupbox>
</vbox>

<vbox id="langSyntaxCheck-Rust">
<groupbox orient="vertical">
<checkbox id="rust.linter.enabled"
label="&basicChecking.label;"
pref="true" />
<hbox>
<description>
&rustChecking.rustcBinary;
</description>
<textbox id="rust.linter.binaries.rustc"
flex="1"
value=''
pref="true"
placeholder="&rustChecking.rustcBinaryPlaceholder;"
preftype="string"/>
<button id='rust_linter_rustc_browse'
label="&browse.label;"
oncommand="languageInfo.Rust.browseForRustcBinary();"/>
</hbox>
<checkbox id="rust.linter.cargo.enabled"
label="&rustChecking.cargoLabel;"
pref="true" />
<hbox>
<description>
&rustChecking.cargoBinary;
</description>
<textbox id="rust.linter.binaries.cargo"
flex="1"
value=''
pref="true"
placeholder="&rustChecking.cargoBinaryPlaceholder;"
preftype="string"/>
<button id='rust_linter_cargo_browse'
label="&browse.label;"
oncommand="languageInfo.Rust.browseForCargoBinary();"/>
</hbox>
</groupbox>
</vbox>

<vbox id="langSyntaxCheck-JavaScript">
<label value="&javaScriptNodeSyntaxSettings.label;" />
<groupbox orient="vertical">
Expand Down
5 changes: 5 additions & 0 deletions src/chrome/komodo/locale/en-US/pref/pref.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -985,3 +985,8 @@ adding an additional caret at the clicked position.">
<!ENTITY label.84 "8.4">
<!ENTITY label.85 "8.5">
<!ENTITY label.86 "8.6">
<!ENTITY rustChecking.rustcBinary "rustc binary:">
<!ENTITY rustChecking.rustcBinaryPlaceholder "Find on PATH...">
<!ENTITY rustChecking.cargoLabel "Enable project-wide cargo syntax checker">
<!ENTITY rustChecking.cargoBinary "cargo binary:">
<!ENTITY rustChecking.cargoBinaryPlaceholder "Find on PATH...">
1 change: 1 addition & 0 deletions src/lint/Conscript
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ $cons->InstallXpcomComponent('koCSSExLinter.py');
$cons->InstallXpcomComponent('koHTMLLinter.py');
$cons->InstallXpcomComponent('koPHPLinter.py');
$cons->InstallXpcomComponent('koJavaScriptLinter.py');
$cons->InstallXpcomComponent('koRustLinter.py');
$cons->InstallXpcomComponent('koLintService.py');
$cons->InstallPythonUtility('koLintResults.py');

Expand Down
128 changes: 128 additions & 0 deletions src/lint/koRustLinter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
from xpcom import components
from koLintResult import KoLintResult, SEV_ERROR, SEV_WARNING, SEV_INFO
from koLintResults import koLintResults
import os
import logging
import process
import koprocessutils
import which
import json
import tempfile

Cc = components.classes
Ci = components.interfaces

log = logging.getLogger("koRustLinter")
log.setLevel(logging.DEBUG)


class KoRustLinter(object):
_com_interfaces_ = [Ci.koILinter]
_reg_clsid_ = "{850fb06c-c8b7-4743-b22c-3d59da3e8f0a}"
_reg_contractid_ = "@activestate.com/koLinter?language=Rust;1"
_reg_categories_ = [
("category-komodo-linter", 'Rust'),
]

def __init__(self,):
self.file_ext = '.rs'
self.project = Cc["@activestate.com/koPartService;1"].getService(Ci.koIPartService)

def lint(self, request):
text = request.content.encode(request.encoding.python_encoding_name)
return self.lint_with_text(request, text)

def _lint_lookup(self, request, linter_name):
try:
linter = request.prefset.getString(
"rust.linter.binaries.{}".format(linter_name),
""
)
if linter == "":
log.debug("Rust: looking for the {} executable on $PATH"
.format(linter_name))
linter = which.which(linter_name)
except which.WhichError:
log.debug("Rust: {} is not found".format(linter_name))
return linter

def lint_with_text(self, request, text):
if not request.prefset.getBoolean("rust.linter.enabled", False):
log.debug("Rust: not enabled")
return koLintResults()

cwd = None
cmd = []

if self.project.currentProject is not None:
if not request.prefset.getBoolean("rust.linter.cargo.enabled", False):
log.debug("Rust: cargo check is disabled")
return koLintResults()
cwd = self.project.currentProject.liveDirectory
linter = {
"type": "cargo",
"binary": self._lint_lookup(request, "cargo")
}
log.debug("Rust: using current project directory and cargo")
else:
cwd = request.cwd
linter = {
"type": "rustc",
"binary": self._lint_lookup(request, "rustc")
}
log.debug("Rust: cwd = {}".format(cwd))

if linter["type"] == "rustc":
tmpfilename = tempfile.mktemp() + self.file_ext
fout = open(tmpfilename, 'wb')
fout.write(text)
fout.close()
cmd = [linter["binary"], "--error-format=json", tmpfilename]
else:
cmd = [linter["binary"], "check", "--message-format", "json", "--color", "never"]

log.debug("Rust: command = {}".format(" ".join(cmd)))

env = koprocessutils.getUserEnv()
cwd = cwd or None
p = process.ProcessOpen(cmd, cwd=cwd, env=env, stdin=process.PIPE)
results = koLintResults()

if linter["type"] == "rustc":
stdout, stderr = p.communicate(input=text)
log.debug(stderr)
errors = map(lambda line: json.loads(line), stderr.splitlines(0))
else:
stdout, stderr = p.communicate()
log.debug(stdout)
errors = map(lambda line: json.loads(line), stdout.splitlines(0))


for error in errors:
try:
if error['features']:
continue
except KeyError:
if linter["type"] == "cargo":
error = error["message"]
message = error["message"]
if error["level"] == "error":
severity = SEV_ERROR
elif error["level"] == "warning":
severity = SEV_WARNING
else:
severity = SEV_INFO
for span in error['spans']:
line = span['line_start'] - 1
for h in span["text"]: # each highlight is a line
line += 1
column_start = h["highlight_start"]
column_end = h["highlight_end"]
result = KoLintResult(description=message,
severity=severity,
lineStart=line,
lineEnd=line,
columnStart=column_start,
columnEnd=column_end)
results.addResult(result)
return results
4 changes: 4 additions & 0 deletions src/python-sitelib/langinfo_prog.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,3 +728,7 @@ class SwiftScriptLangInfo(LangInfo):
name = "Swift"
exts = ['.swift']

class RustLangInfo(LangInfo):
"""https://rust-lang.org"""
name = "Rust"
exts = ['.rs']
6 changes: 6 additions & 0 deletions src/udl/Conscript
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ my @lexers = (
codename => "haml_language",
udl_path => "haml-mainlex.udl",
skel => "skel/Haml",
},
{
language_name => "Rust",
codename => "rust_language",
udl_path => "rust-mainlex.udl",
skel => "skel/Rust",
}
);
foreach my $info (@lexers) {
Expand Down
3 changes: 2 additions & 1 deletion src/udl/GUIDs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ ActionScript 4dd22f3a-52e2-426d-8a21-6f7ea2ba91ac
reStructuredText d98cc808-2981-4aa0-841b-e5e920d83177
TracWiki b843faa8-aeea-4fcb-aeb9-36c4483c6f95
Docker 54072a7f-a845-4b78-b63f-fc47c583e0b8
R ec4a2833-5994-4c94-9be5-db6a8952029f
R ec4a2833-5994-4c94-9be5-db6a8952029f
Rust FABBE082-7E14-41C3-92EA-90F5CB95519C
69 changes: 69 additions & 0 deletions src/udl/skel/Rust/components/koRust_UDL_Language.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!python
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is Komodo code.
#
# The Initial Developer of the Original Code is ActiveState Software Inc.
# Portions created by ActiveState Software Inc are Copyright (C) 2000-2007
# ActiveState Software Inc. All Rights Reserved.
#
# Contributor(s):
# ActiveState Software Inc
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

"""Language package for Rust"""

import logging
from koUDLLanguageBase import KoUDLLanguage

log = logging.getLogger("koRustLanguage")
log.setLevel(logging.DEBUG)

def registerLanguage(registry):
log.debug("Registering language Rust")
registry.registerLanguage(KoRustLanguage())

class KoRustLanguage(KoUDLLanguage):
name = "Rust"
_reg_desc_ = "%s Language" % name
_reg_contractid_ = "@activestate.com/koLanguage?language=%s;1" \
% (name)
_reg_clsid_ = "{FABBE082-7E14-41C3-92EA-90F5CB95519C}"
_reg_categories_ = [("komodo-language", name)]

lexresLangName = "Rust"
lang_from_udl_family = {'SSL': 'Rust'}

accessKey = 'r'
primary = 1
defaultExtension = ".rs"
downloadURL = 'http://rust-lang.org/'
commentDelimiterInfo = {
"line": [ "//" ],
"block": [ ("/*", "*/") ],
}
supportsSmartIndent = "brace"
Loading