mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 09:33:34 -06:00
fixed sorting of functions, and lexing parsing fix for unclosed string params
This commit is contained in:
parent
38609fb964
commit
2acfa83b76
@ -27,8 +27,8 @@ function (angular, _, config, graphiteFuncs, Parser) {
|
||||
var parser = new Parser($scope.target.target);
|
||||
var astNode = parser.getAst();
|
||||
|
||||
if (parser.error) {
|
||||
$scope.parserError = parser.error.text + " at position: " + parser.error.pos;
|
||||
if (astNode.type === 'error') {
|
||||
$scope.parserError = astNode.message + " at position: " + astNode.pos;
|
||||
$scope.showTextEditor = true;
|
||||
return;
|
||||
}
|
||||
|
@ -124,6 +124,10 @@ function (_) {
|
||||
defaultParams: ['1d']
|
||||
});
|
||||
|
||||
_.each(categories, function(funcList, catName) {
|
||||
categories[catName] = _.sortBy(funcList, 'name');
|
||||
});
|
||||
|
||||
function FuncInstance(funcDef) {
|
||||
this.def = funcDef;
|
||||
this.params = funcDef.defaultParams.slice(0);
|
||||
|
@ -591,6 +591,15 @@ define([
|
||||
this.skip();
|
||||
|
||||
while (this.peek() !== quote) {
|
||||
if (this.peek() === "") { // End Of Line
|
||||
return {
|
||||
type: 'string',
|
||||
value: value,
|
||||
isUnclosed: true,
|
||||
quote: quote,
|
||||
pos: this.char
|
||||
};
|
||||
}
|
||||
|
||||
var char = this.peek();
|
||||
var jump = 1; // A length of a jump, after we're done
|
||||
|
@ -3,25 +3,13 @@ define([
|
||||
], function (Lexer) {
|
||||
'use strict';
|
||||
|
||||
var NodeTypes = {
|
||||
MetricExpression: 1,
|
||||
MetricNode: 2,
|
||||
FunctionCall: 4,
|
||||
NumericLiteral: 5,
|
||||
StringLiteral: 6
|
||||
};
|
||||
|
||||
function Parser(expression) {
|
||||
this.expression = expression;
|
||||
this.lexer = new Lexer(expression);
|
||||
this.state = "start";
|
||||
this.error = null;
|
||||
this.tokens = this.lexer.tokenize();
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
Parser.Nodes = NodeTypes;
|
||||
|
||||
Parser.prototype = {
|
||||
|
||||
getAst: function () {
|
||||
@ -29,7 +17,16 @@ define([
|
||||
},
|
||||
|
||||
start: function () {
|
||||
return this.functionCall() || this.metricExpression();
|
||||
try {
|
||||
return this.functionCall() || this.metricExpression();
|
||||
}
|
||||
catch(e) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: e.message,
|
||||
pos: e.pos
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
metricExpression: function() {
|
||||
@ -52,7 +49,6 @@ define([
|
||||
var rest = this.metricExpression();
|
||||
if (!rest) {
|
||||
this.errorMark('Expected metric identifier');
|
||||
return null;
|
||||
}
|
||||
|
||||
node.segments = node.segments.concat(rest.segments);
|
||||
@ -77,7 +73,6 @@ define([
|
||||
|
||||
if (!this.match(')')) {
|
||||
this.errorMark('Expected closing paranthesis');
|
||||
return null;
|
||||
}
|
||||
|
||||
this.index++;
|
||||
@ -122,19 +117,24 @@ define([
|
||||
return null;
|
||||
}
|
||||
|
||||
var token = this.tokens[this.index];
|
||||
if (token.isUnclosed) {
|
||||
throw { message: 'Unclosed string parameter', pos: token.pos };
|
||||
}
|
||||
|
||||
this.index++;
|
||||
|
||||
return {
|
||||
type: 'string',
|
||||
value: this.tokens[this.index-1].value
|
||||
value: token.value
|
||||
};
|
||||
},
|
||||
|
||||
errorMark: function(text) {
|
||||
var currentToken = this.tokens[this.index];
|
||||
var type = currentToken ? currentToken.type : 'end of string';
|
||||
this.error = {
|
||||
text: text + " instead found " + type,
|
||||
throw {
|
||||
message: text + " instead found " + type,
|
||||
pos: currentToken ? currentToken.pos : this.lexer.char
|
||||
};
|
||||
},
|
||||
|
@ -30,6 +30,19 @@ define([
|
||||
expect(tokens[tokens.length - 1].value).to.be(')');
|
||||
});
|
||||
|
||||
it('should handle error with unterminated string', function() {
|
||||
var lexer = new Lexer("alias(metric, 'asd)");
|
||||
var tokens = lexer.tokenize();
|
||||
expect(tokens[0].value).to.be('alias');
|
||||
expect(tokens[1].value).to.be('(');
|
||||
expect(tokens[2].value).to.be('metric');
|
||||
expect(tokens[3].value).to.be(',');
|
||||
expect(tokens[4].type).to.be('string');
|
||||
expect(tokens[4].isUnclosed).to.be(true);
|
||||
expect(tokens[4].pos).to.be(20);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -8,7 +8,6 @@ define([
|
||||
var parser = new Parser('metric.test.*.asd.count');
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error).to.be(null);
|
||||
expect(rootNode.type).to.be('metric');
|
||||
expect(rootNode.segments.length).to.be(5);
|
||||
expect(rootNode.segments[0].value).to.be('metric');
|
||||
@ -17,7 +16,6 @@ define([
|
||||
it('simple function', function() {
|
||||
var parser = new Parser('sum(test)');
|
||||
var rootNode = parser.getAst();
|
||||
expect(parser.error).to.be(null);
|
||||
expect(rootNode.type).to.be('function');
|
||||
expect(rootNode.params.length).to.be(1);
|
||||
});
|
||||
@ -26,7 +24,6 @@ define([
|
||||
var parser = new Parser("sum(test, 1, 'test')");
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error).to.be(null);
|
||||
expect(rootNode.type).to.be('function');
|
||||
expect(rootNode.params.length).to.be(3);
|
||||
expect(rootNode.params[0].type).to.be('metric');
|
||||
@ -38,7 +35,6 @@ define([
|
||||
var parser = new Parser("sum(scaleToSeconds(test, 1))");
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error).to.be(null);
|
||||
expect(rootNode.type).to.be('function');
|
||||
expect(rootNode.params.length).to.be(1);
|
||||
expect(rootNode.params[0].type).to.be('function');
|
||||
@ -52,7 +48,6 @@ define([
|
||||
var parser = new Parser("sum(test.test.*.count, test.timers.*.count)");
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error).to.be(null);
|
||||
expect(rootNode.type).to.be('function');
|
||||
expect(rootNode.params.length).to.be(2);
|
||||
expect(rootNode.params[0].type).to.be('metric');
|
||||
@ -63,16 +58,24 @@ define([
|
||||
var parser = new Parser('metric.test.*.asd.');
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error.text).to.be('Expected metric identifier instead found end of string');
|
||||
expect(parser.error.pos).to.be(19);
|
||||
expect(rootNode.message).to.be('Expected metric identifier instead found end of string');
|
||||
expect(rootNode.pos).to.be(19);
|
||||
});
|
||||
|
||||
it('invalid function expression missing closing paranthesis', function() {
|
||||
var parser = new Parser('sum(test');
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(parser.error.text).to.be('Expected closing paranthesis instead found end of string');
|
||||
expect(parser.error.pos).to.be(9);
|
||||
expect(rootNode.message).to.be('Expected closing paranthesis instead found end of string');
|
||||
expect(rootNode.pos).to.be(9);
|
||||
});
|
||||
|
||||
it('unclosed string in function', function() {
|
||||
var parser = new Parser("sum('test)");
|
||||
var rootNode = parser.getAst();
|
||||
|
||||
expect(rootNode.message).to.be('Unclosed string parameter');
|
||||
expect(rootNode.pos).to.be(11);
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user