Skip to content

Commit

Permalink
Merge pull request #62 from Quodatum/dev
Browse files Browse the repository at this point in the history
Dev 0.6.2
  • Loading branch information
apb2006 authored Apr 8, 2024
2 parents 7b09787 + 59f3b84 commit 292faaa
Show file tree
Hide file tree
Showing 23 changed files with 482 additions and 227 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
"titleBar.inactiveBackground": "#00cc9999",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.remoteColor": "#00CC99"
"peacock.remoteColor": "#00CC99",
"basexTools.xquery.profile": "basex-10"
}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# [0.6.2] 2024-03-31
* inherit processor when importing modules
# [0.6.1] 2024-01-13
* Java function call handling
* xq-catalogs 0.1.2 (%perm)
# [0.6.0] 2023-12-05
* add namespace to DocLink
* suppress XQLT0001 when no content
# [0.5.1] 2023-11-26
* fix typedefs
# [0.5.0] 2023-11-26
Expand Down
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ module.exports = function (grunt) {
// String or array of strings
// determining which files to include.
// This option is grunt's "full" file format.
src: ['test/type_test.js']
src: ['test/module_resolver_test.js']
//src: ['test/issue_test.js']
//src: ['test/stylecheck_test.js']
//src: ['test/function_test.js']
Expand Down
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/quodatum/xqlint/release.yml)
[![Libraries.io dependency status for latest release, scoped npm package](https://img.shields.io/librariesio/release/npm/@quodatum/xqlint)](https://www.npmjs.com/package/@quodatum/xqlint)

[npm @quodatum/xqlint](https://www.npmjs.com/package/@quodatum/xqlint)

XQLint parses XQuery files and returns errors and warnings based on static code analysis. It provides the following features:
* Lint: errors and warnings based on static code analysis.
Expand Down
Binary file removed docs/lint.png
Binary file not shown.
29 changes: 22 additions & 7 deletions docs/markers.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,30 @@
## standard
see https://docs.basex.org/wiki/XQuery_Errors
messages..
```javascript
StaticWarning('W01', 'Avoid this type of import. Use import module namespace instead', pos);
StaticWarning('W02', '"' + uri + '" already bound to the "' + namespace.prefixes.join(', ') + '" prefix', pos);
### W01
`StaticWarning('W01', 'Avoid this type of import. Use import module namespace instead', pos);`
### W02
`StaticWarning('W02', '"' + uri + '" already bound to the "' + namespace.prefixes.join(', ') + '" prefix', pos);`

### W03
```
addWarning('W03', 'Unused variable "' + rootStcx.variables[key].qname.name + '"', rootStcx.variables[key].pos);
```
### W04
```
addWarning('W04', 'Unused module "' + uri + '"', namespace.pos);
```
### W05
addWarning('W05', 'Untyped return value', name.pos);

### XQST0009
addWarning('XQST0009', 'No XML Schema support "' + uri + '"', namespace.pos);

### XQST0059
StaticError('XQST0059', 'module "' + uri + '" not found', pos);
### XQST0088
StaticError('XQST0088', 'empty target namespace in module import or module declaration', pos);
### XQST0047
StaticError('XQST0047', '"' + uri + '": duplicate target namespace', pos);

StaticError('XQST0033', '"' + prefix + '": namespace prefix already bound to "' + namespace.uri + '"', pos);
StaticError('XPST0081', '"' + qname.prefix + '": can not expand prefix of lexical QName to namespace URI', pos);
StaticError('XQST0048', '"' + qname.prefix + ':' + qname.name + '": Qname not library namespace', pos);
Expand All @@ -31,9 +42,13 @@ StaticError('XPST0008', '"' + qname.name + '": undeclared variable', pos);
StaticError('XPST0008', '"' + qname.name + '#' + arity + '": undeclared function', pos);
StaticError('XQST0048', '"' + qname.prefix + ':' + qname.name + '": Qname not library namespace', pos);
StaticError('XQST0034', '"' + qname.name + '": duplicate function declaration', pos);
```

### formatter/style_check.js
### XPST0003 :Parse error
### XQLT0001 :Unparsed due to previous parser error



## formatter/style_check.js

* [SW01] Detected CRLF
* [SW02] Tabs detected
Expand Down
17 changes: 12 additions & 5 deletions lib/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,19 @@ astCmd

var xqdocCmd = cli.command('xqdoc <path>');
xqdocCmd
.option(
'-p, --profile <name>',
'XQuery profile (e.g. basex-10)',
function(value) {
return value.toLowerCase();
}
)
.description('Print Module XQDoc. A custom json format.')
.action(function(p){
.action(function(p,xqdocCmd){
var files = getFiles(p);
files.forEach(function(file){
var source = fs.readFileSync(file, 'utf-8');
var linter = new XQLint(source, { fileName: file, styleCheck: false });
var linter = new XQLint(source, { fileName: file, styleCheck: false , processor: xqdocCmd.profile });
var xqdoc = linter.getXQDoc();
console.log(JSON.stringify(xqdoc, null, 2));
});
Expand All @@ -108,8 +115,8 @@ lintCmd.option(
}
)
.option(
'-p, --processor <name>',
'XQuery Processor (e.g. basex-10)',
'-p, --profile <name>',
'XQuery profile (e.g. basex-10)',
function(value) {
return value.toLowerCase();
}
Expand All @@ -128,7 +135,7 @@ lintCmd.option(
};
files.forEach(function(file){
var source = fs.readFileSync(file, 'utf-8').replace(/^\uFEFF/, '');
var linter = new XQLint(source, { fileName: file, styleCheck: lintCmd.styleCheck, processor: lintCmd.processor });
var linter = new XQLint(source, { fileName: file, styleCheck: lintCmd.styleCheck, processor: lintCmd.profile });
var markers = linter.getMarkers().sort(function(a, b){ return a.sl - b.sl; });
var lines = source.split('\n');
if(markers.length !== 0) {
Expand Down
10 changes: 7 additions & 3 deletions lib/compiler/static_context.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,6 @@ exports.StaticContext = function (parent, pos, processor,baseUri) {
return this;
},



getAvailableModuleNamespaces: function () {
return this.root.availableModuleNamespaces;
},
Expand Down Expand Up @@ -307,10 +305,14 @@ exports.StaticContext = function (parent, pos, processor,baseUri) {
pos: pos,
type: type
};

if(type === 'module' && !namespace && ats.length==0) {
//'todo REPO check
throw new StaticError('XQST0059', 'module "' + uri + '" not found', pos);
}
if (namespace && !namespace.override && !(namespace.uri = uri)) {
throw new StaticWarning('W02', '"' + uri + '" already bound to the "' + namespace.prefixes.join(', ') + '" prefix', pos);
}

if (ats && ats.length) {
//console.log(ats[0].url,"*" ,this.baseUri);
this.namespaces[uri].ats = ats.map(setBase,this);
Expand Down Expand Up @@ -461,6 +463,8 @@ exports.StaticContext = function (parent, pos, processor,baseUri) {
if ((qname.uri === 'http://www.w3.org/2005/xpath-functions' ||
(qname.uri === '' && this.root.defaultFunctionNamespaces.concat(this.root.defaultFunctionNamespace).indexOf('http://www.w3.org/2005/xpath-functions') !== -1)) && qname.name === 'concat') {
//do nothing
} else if(qname.uri.startsWith("java:")){

} else if (!fn) {
throw new StaticError('XPST0008', '"' + qname.name + '#' + arity + '": undeclared function', pos);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/compiler/translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ exports.Translator = function (rootStcx, ast) {
var markers = [];

var addStaticError = function (e) {
markers.push({
const marker={
pos: e.getPos(),
code: e.getCode(),
level: 'error',
message: '[' + e.getCode() + '] ' + e.getMessage()
});
};
markers.push(marker);
};

var addWarning = function (code, message, pos) {
Expand Down
2 changes: 1 addition & 1 deletion lib/xqdoc/parse_comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ exports.parseComment = function (comment) {

switch (tag) {
case "description":
ann.description += ' ' + line;
ann.description += line+' ' ;
break;
case "param":
if (hasTag) {
Expand Down
1 change: 1 addition & 0 deletions lib/xqdoc/xqdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ exports.XQDoc = function (ast,sctx) {
this.getXQDoc = function (withPos) {
var doc = {
ns: sctx.moduleNamespace,
description:"todo",
prefixes: [prefix],
namespaces: [],
variables: [],
Expand Down
71 changes: 43 additions & 28 deletions lib/xqlint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ declare module '@quodatum/xqlint' {
public getErrors(): Marker[];
public getWarnings(): Marker[];

public getNamespaces() :Namespaces;
public getNamespaces(): Namespaces;
public getDocLinks(): DocLink[];

public getProcessor(): string;
Expand All @@ -28,19 +28,19 @@ declare module '@quodatum/xqlint' {
export function createStaticContext(processor: string, fileName?: string): any;
export function CodeFormatter(ast: object): any;
export function CodeFormatter(ast: object, newLinesEnabled: boolean, DEBUG: any): any;

export class XQLintOptions {
processor: string;
fileName?: string; // full path
styleCheck?: boolean;
}
export class XQLintCompletion {
name :string;
value :string;
meta :string; //eg type
priority? :number;
identifierRegex? :string; // nameCharRegExp,
snippet? :string // snippets[name]
name: string;
value: string;
meta: string; //eg type
priority?: number;
identifierRegex?: string; // nameCharRegExp,
snippet?: string // snippets[name]
}
//
export class Marker {
Expand All @@ -51,7 +51,7 @@ declare module '@quodatum/xqlint' {
}

//

export class LintRange {
sl: number;
sc: number;
Expand All @@ -60,12 +60,15 @@ declare module '@quodatum/xqlint' {
}

export class XQDoc {
moduleNamespace: string;
ns: string;
prefixes: string[];
description: string;
variables: VarDecl[];
functions: FunDecl[];
queryBody?: LintRange;
}

// abstract syntax tree
export interface Ast {
name: string;
children: Ast[];
Expand All @@ -74,9 +77,20 @@ declare module '@quodatum/xqlint' {
value?: string;
[propName: string]: any;
}
export interface Sctx {


// static context
export interface Sctx {
resolveQName: (value: string, pos: Position) => QName;
getVariable: (qname: QName) => any;
getFunction: (qname: QName, arity: number) => any;
[propName: string]: any;
}
export interface QName {
uri: string;
prefix: string;
name: string;
}

export interface VarDecl {
name: string;
type: string;
Expand All @@ -99,28 +113,29 @@ declare module '@quodatum/xqlint' {
others: string[];
}
export interface Profile {
id :string;
description :string;
modules :string[];
id: string;
description: string;
modules: string[];
}
export type Namespaces ={
[uri: string]: Namespace;
export type Namespaces = {
[uri: string]: Namespace;
}
export interface Namespace {
type :string; //declare or module
prefixes :string[] //
override? :boolean;
pos : LintRange;
ats? : AtLocation[];
uri? :string; //set by getnamespace from prefix
type: string; //declare or module
prefixes: string[] //
override?: boolean;
pos: LintRange;
ats?: AtLocation[];
uri?: string; //set by getnamespace from prefix
}
export interface AtLocation {
url :string; // path to import, maybe relative eg 'page.xqm'
pos : LintRange; // range of uri string
baseUri? :string; // base URI of source
url: string; // path to import, maybe relative eg 'page.xqm'
pos: LintRange; // range of uri string
baseUri?: string; // base URI of source
}
export interface DocLink {
path :string; // full path to import
pos : LintRange; // range of uri string
ns: string; // namespace
path: string; // full path to import
pos: LintRange; // range of uri string
}
}
Loading

0 comments on commit 292faaa

Please sign in to comment.