Skip to content

Commit

Permalink
Update for Zephyr 2.2
Browse files Browse the repository at this point in the history
- Allows phandles without enclosing <> brackets.
- Default include is *.dts, not *.dts_compiled
- phandle arrays fetch parameter names from handle type
- Include all dependencies, resolving build errors on windows
  • Loading branch information
trond-snekvik committed Apr 10, 2020
1 parent aad3b69 commit 7cd7032
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 21 deletions.
19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "devicetree",
"displayName": "devicetree",
"description": "Code completion, syntax highlighting and linting of DeviceTree configurations",
"version": "1.0.0",
"version": "1.1.0",
"publisher": "trond-snekvik",
"engines": {
"vscode": "^1.12.0"
"vscode": "^1.43.0"
},
"categories": [
"Other"
Expand Down Expand Up @@ -50,13 +50,17 @@
"properties": {
"devicetree.autoincludes": {
"type": "array",
"description": "List of glob patterns for files that are automatically included and parsed before the open file. May include VSCode variables, like ${workspaceFolder}. Defaults to ./build/**/*.dts_compiled",
"default": ["./build/**/*.dts_compiled"]
"description": "List of glob patterns for files that are automatically included and parsed before the open file. May include VSCode variables, like ${workspaceFolder}. Defaults to ./build/**/*.dts",
"default": [
"./build/**/*.dts"
]
},
"devicetree.bindings": {
"type": "array",
"description": "List of directories containing binding descriptors. Relative paths are executed from each workspace. Defaults to dts/bindings",
"default": ["dts/bindings"]
"default": [
"dts/bindings"
]
}
}
}
Expand All @@ -73,11 +77,16 @@
"@types/mocha": "^2.2.32",
"@types/node": "^6.0.40",
"@types/yaml": "^1.2.0",
"@types/vscode": "^1.43.0",
"@types/js-yaml": "3.11.1",
"@types/glob": "5.0.35",
"mocha": "^2.3.3",
"typescript": "^3.7.2"
},
"dependencies": {
"find": "^0.3.0",
"glob": "7.1.6",
"js-yaml": "^3.13.1",
"yaml": "^1.7.2"
}
}
79 changes: 71 additions & 8 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function getAutoIncludes(dir: string): string[] {
return fullMatch;
});
})
return glob.sync('{' + patterns.join(',') + '}', {cwd: dir, absolute: true, nosort: true}).map(p => path.resolve(dir, p));
return glob.sync('{' + patterns.join(',') + ',}', {cwd: dir, absolute: true, nosort: true}).map(p => path.resolve(dir, p));
}

function appendPropSnippet(p: types.PropertyType, snippet: vscode.SnippetString, parent?: parser.Node, parentType?: types.NodeType, node?: parser.Node) {
Expand Down Expand Up @@ -210,13 +210,15 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
bindingDirs.forEach(d => this.types.addFolder(d));
console.log(`Found ${Object.keys(this.types.types).length} bindings in ${bindingDirs.join(', ')}`);

this.setDoc(vscode.window.activeTextEditor.document)
if (vscode.window.activeTextEditor) {
this.setDoc(vscode.window.activeTextEditor.document)
}
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(editor => this.setDoc(editor.document)));
context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(change => this.parseDoc(change.document)));
}

addMissing(entry: parser.NodeEntry, propType: types.PropertyType) {
if (vscode.window.activeTextEditor.document.uri.fsPath !== entry.range.doc.uri.fsPath) {
if (!vscode.window.activeTextEditor || vscode.window.activeTextEditor.document.uri.fsPath !== entry.range.doc.uri.fsPath) {
return;
}
var indent = vscode.window.activeTextEditor.options.insertSpaces ? ' '.repeat(vscode.window.activeTextEditor.options.tabSize as number) : '\t';
Expand Down Expand Up @@ -400,6 +402,14 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
}
}

} else if (prop.name === 'status') {
// Kind of intrusive? Also needs to go on every entry for this node.
// if (prop.value.value === 'disabled') {
// var diag = new vscode.Diagnostic(entry.range.toRange(), `Disabled`, vscode.DiagnosticSeverity.Hint);
// diag.tags = [vscode.DiagnosticTag.Unnecessary];
// diag.relatedInformation = [new vscode.DiagnosticRelatedInformation(new vscode.Location(prop.range.doc.uri, prop.range.toRange()), `Disabled here`)];
// diags.push(diag);
// }
} else if (propType.type === 'phandle-array' && Array.isArray(prop.value.value)) {
var c = getPHandleCells(prop.name, node.parent);
if (c) {
Expand Down Expand Up @@ -519,7 +529,12 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
var expanded = `${node.fullName} {`;

expanded += node.uniqueProperties().map(p => `\n\t${p.toString()};`).join('');
expanded += node.children().map(c => `\n\t${c.name} { /* ... */ };`).join('');
expanded += node.children().reduce((array, curr) => {
if (!array.find(c => c.name === curr.name)) {
array.push(curr);
}
return array;
}, new Array<parser.Node>()).map(c => `\n\t${c.name} { /* ... */ };`).join('');
expanded += '\n};';

return new vscode.Hover([new vscode.MarkdownString('`' + node.path + '`'), {language: 'dts', value: expanded}], bundle[0]);
Expand All @@ -538,20 +553,36 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
var type = this.types.nodeType(node, node.parent && this.types.nodeType(node.parent));
var prop = type.properties.find(p => p.name === symbol);
if (prop) {
var results: vscode.MarkedString[] = [new vscode.MarkdownString('type: `' + (Array.isArray(prop.type) ? prop.type.join('`, `') : prop.type) + '`')];
var results: vscode.MarkedString[] = [];
if (prop.description) {
results.push(new vscode.MarkdownString(prop.description));
}
results.push(new vscode.MarkdownString('type: `' + (Array.isArray(prop.type) ? prop.type.join('`, `') : prop.type) + '`'));
return new vscode.Hover(results, word);
}

var entry = node.entries.find(e => e.nameRange.contains(position, document));
if (entry) {
var results: vscode.MarkedString[] = [];
if (type.title) {
results.push(new vscode.MarkdownString(type.title));
}
if (type.description) {
results.push(new vscode.MarkdownString(type.description));
}

results.push(new vscode.MarkdownString('`' + node.path + '`'));

return new vscode.Hover(results, word)
}
}

provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.ProviderResult<vscode.Definition> {
if (document.languageId === 'yaml') {
var range = document.getWordRangeAtPosition(position, /[\w\-\.,]+\.ya?ml/);
var text = document.getText(range);
if (text) {
var type = Object.keys(this.types.types).map(t => this.types.types[t]).find(t => t.filename.match(new RegExp('.*/' + text)));
var type = Object.keys(this.types.types).map(t => this.types.types[t]).find(t => t?.filename.match(new RegExp('.*/' + text)));
if (type) {
return new vscode.Location(vscode.Uri.file(type.filename), new vscode.Position(0, 0));
}
Expand Down Expand Up @@ -580,7 +611,7 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
}

if (property[1].name === 'compatible') {
var type = this.types.get(symbol);
var type = this.types.nodeType(property[0]);
if (type && type.filename.length > 0) {
return new vscode.Location(vscode.Uri.file(type.filename), new vscode.Position(0, 0));
}
Expand Down Expand Up @@ -716,7 +747,7 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
if (!braces) {
completion.insertText = propValueTemplate(t, 'string');
}
if (this.types.types[t].loaded) {
if (this.types.types[t]?.loaded) {
completion.detail = this.types.types[t].title;
completion.documentation = this.types.types[t].description;
}
Expand Down Expand Up @@ -816,6 +847,16 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
return;
}

if (propType.type === 'int' && propType.description) {
var info = new vscode.SignatureInformation(`${prop[0].path}${prop[1].name}`, propType.description);
info.parameters = [new vscode.ParameterInformation(`number`)];
var help = new vscode.SignatureHelp();
help.activeParameter = 0;
help.activeSignature = 0;
help.signatures = [info];
return help;
}

if (propType.type !== 'phandle-array' && propType.type !== 'array') {
return;
}
Expand All @@ -828,6 +869,7 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
return;
}

var paramValues: string[] = [];
var paramStarts: number[] = [];
var paramOffset = 0;
while (rawVal.length) {
Expand All @@ -839,7 +881,9 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
continue;
}


if (rawVal.match(/^\(/)) {
var paramValue = '(';
paramStarts.push(paramOffset);
paramOffset++;
rawVal = rawVal.slice(1);
Expand All @@ -848,11 +892,14 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
while (parenLvl > 0 && (match = rawVal.match(/^.*?([()])/))) {
parenLvl += 2 * Number(match[1] === '(') - 1;
paramOffset += match[0].length;
paramValue += match[0];
rawVal = rawVal.slice(match[0].length);
}
if (parenLvl > 0) {
break;
}

paramValues.push(paramValue);
continue;
}

Expand All @@ -861,6 +908,7 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
paramStarts.push(paramOffset);
paramOffset += paramMatch[0].length;
rawVal = rawVal.slice(paramMatch[0].length);
paramValues.push(paramMatch[0]);
continue;
}
break;
Expand All @@ -875,10 +923,25 @@ class DTSEngine implements vscode.DocumentSymbolProvider, vscode.DefinitionProvi
var cells = getCells(prop[1].name, prop[0].parent);
if (cells) {
params = cells;
} else if (propType.type === 'phandle-array') {
var ref : parser.Node;
if (paramValues.length > 0 && prop[1].name.endsWith('s') && (ref = this.parser.getPHandleNode(paramValues[0].slice(1)))) {
// referenced node type should have a top level entry called {prop[0:-1]}-cells,
// e.g. if the property is 'pwms', the referenced type should have an entry 'pwm-cells' that's a list of the parameter names:
var cellCountPropName = prop[1].name.slice(0, prop[1].name.length - 1) + '-cells';
var refType = this.types.nodeType(ref);
if (refType && (cellCountPropName in refType)) {
params = [paramValues[0], ...refType[cellCountPropName]];
}
}
} else {
params = Array((<[]>prop[1].value.value).length).fill('').map((_, i) => `param-${i+1}`);
}

if (!params) {
return;
}

var signature = prop[1].name + ` = < ${params.join(' ')} >;`;

var info = new vscode.SignatureInformation(signature, propType.description);
Expand Down
11 changes: 9 additions & 2 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ function parsePropValue(value: string, range: OffsetRange, diags: vscode.Diagnos
continue;
}

var reference = state.match(/^&([\w\-]+)/);
if (reference) {
elems.push(<PHandle>{node: reference[1]});
continue;
}

var string = state.match(/^"(.*?)"/);
if (string) {
elems.push(string[1]);
Expand Down Expand Up @@ -480,7 +486,7 @@ export class Parser {
}
nodeStack.push(entry);

if (nodeMatch[3] && nodeMatch[3].startsWith('0')) {
if (nodeMatch[3] && nodeMatch[3].length > 1 && nodeMatch[3].startsWith('0')) {
diags.push(new vscode.Diagnostic(entry.nameRange.toRange(), `Address should not start with leading 0's`, vscode.DiagnosticSeverity.Warning));
}
continue;
Expand Down Expand Up @@ -591,7 +597,8 @@ export class Parser {

getPropertyAt(pos: vscode.Position, doc: vscode.TextDocument): [Node, Property] | undefined {
var node = this.getNodeAt(pos, doc);
var prop = node.properties().find(p => p.range.doc.uri.fsPath === doc.uri.fsPath && p.range.toRange().contains(pos));

var prop = node?.properties().find(p => p.range.doc.uri.fsPath === doc.uri.fsPath && p.range.toRange().contains(pos));
if (prop) {
return [node, prop];
}
Expand Down
21 changes: 15 additions & 6 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as yaml from 'yaml';
import * as yaml from 'js-yaml';
import * as glob from 'glob';
import * as vscode from 'vscode';
import { readFileSync, fstat } from 'fs';
import { Node, Property } from './parser';
import { Diagnostic, DiagnosticSeverity } from 'vscode';
Expand Down Expand Up @@ -389,7 +390,7 @@ export class TypeLoader {
return undefined;
}

if (load && !this.types[typeName].loaded) {
if (load && !this.types[typeName]?.loaded) {
this.types[typeName] = this.loadYAML(typeName);
}

Expand Down Expand Up @@ -434,12 +435,20 @@ export class TypeLoader {
return type;
}

loadYAML(name: string): NodeType {
loadYAML(name: string): NodeType | null {
var type = this.types[name];
var contents = readFileSync(type.filename, 'utf-8');
var tree = yaml.parse(contents);
if (!type) {
return null;
}

return this.YAMLtoNode(tree, type);
var contents = readFileSync(type.filename, 'utf-8');
try {
var tree = yaml.load(contents);
// var tree = yaml.parse(contents, {mapAsMap: true});
return this.YAMLtoNode(tree, type);
} catch (e) {
vscode.window.showWarningMessage(`Invalid type file "${name}.yaml": ${e}`);
}
}


Expand Down

0 comments on commit 7cd7032

Please sign in to comment.