This repository was archived by the owner on Sep 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Initial commit of Analyzer-based Linter. Ported over first linter 'unbalanced-delimiters' #1
Closed
Closed
Changes from 9 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
0bb82d2
Initial commit of Analyzer-based Linter. Ported over first linter 'u…
usergenic 2a5a238
Upgraded to polymer-analyzer 2.0.0-alpha.12 and removed the utils mod…
usergenic 95d6cda
Set version to 1.0.0-alpha.1
usergenic 87102ef
Added support for WarningCarryingException handling in Linter.
usergenic 1d9ae8b
Added a Rule to catch WarningCarryingException.
usergenic 8731da5
Address PR comments for unbalanced delimiters rule.
usergenic 7433baf
Bumped analyzer version to 2.0.0-alpha.14
usergenic d192602
Added linter behavior/test to deal with WarningsCarryingException
usergenic 7e32f93
Updated analyzer warnings test for style
usergenic e189edc
Added native attribute binding rule.
usergenic 93a0c41
Added all the old polylint sample fixtures.
usergenic 0a4211d
Updated README ever-so-slightly.
usergenic e45c72a
Updated the bad binding expression messages to be nice like @rictic s…
usergenic 38fea61
Merge branch 'master' into brand-new-linter
rictic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
|
||
// TODO(usergenic): Migrate this to polymer-analyzer | ||
// https://github.com/Polymer/polymer-analyzer/issues/351 | ||
|
||
/** | ||
* A parsed polymer binding expression | ||
* @param {Array.<string>} keys The keys referenced by this expression. | ||
* @param {Array.<string>} methods The methods referenced by this expression. | ||
* @param {string} type One of 'computed', 'literal', or 'reference' | ||
* @param {string} raw The unparsed expression | ||
*/ | ||
export class ParsedExpression { | ||
public keys: Array<string>; | ||
public methods: Array<string>; | ||
public type: string; | ||
public raw: string; | ||
} | ||
|
||
export interface Signature { | ||
method: string; | ||
static: boolean; | ||
args?: Argument[]; | ||
} | ||
|
||
export interface Argument { | ||
name: string; | ||
value?: string|number; | ||
literal?: boolean; | ||
structured?: boolean; | ||
wildcard?: boolean; | ||
} | ||
|
||
function primaryName(expression: string): string { | ||
// TODO(usergenic): Remove this commented out section copied in from polylint | ||
// if (expression.name) { | ||
// expression = expression.name; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this was sometimes an |
||
// } | ||
if (expression.match(/^('|").*('|")$/)) { // string literal | ||
return ''; | ||
} | ||
if (expression.match(/^-?\d*\.?\d+$/)) { // number literal | ||
return ''; | ||
} | ||
if (expression.indexOf('!') === 0) { | ||
return primaryName(expression.slice(1)); | ||
} | ||
if (expression.indexOf('.') === -1) { | ||
return expression; | ||
} else { | ||
return expression.split('.')[0]; | ||
} | ||
} | ||
|
||
export class ExpressionParser { | ||
public extractBindingExpression(text: string): string { | ||
const match = text.match(/\{\{(.*)\}\}/) || text.match(/\[\[(.*)\]\]/); | ||
if (match && match.length === 2) { | ||
let expression: string = match[1]; | ||
if (expression.indexOf('::') > -1) { | ||
expression = expression.slice(0, expression.indexOf('::')); | ||
} | ||
return expression.trim(); | ||
} | ||
return ''; | ||
} | ||
|
||
public parseExpression(expression: string): ParsedExpression { | ||
const parsed = new ParsedExpression(); | ||
parsed.raw = expression; | ||
|
||
const unwrapped = this.extractBindingExpression(expression); | ||
const parsedMethod = this._parseMethod(unwrapped); | ||
if (parsedMethod) { | ||
parsed.type = 'computed'; | ||
parsed.keys = parsedMethod.args!.map((arg) => primaryName(arg.name)); | ||
parsed.methods = [parsedMethod.method]; | ||
} else { | ||
parsed.type = 'reference'; | ||
parsed.methods = []; | ||
parsed.keys = [primaryName(unwrapped)]; | ||
} | ||
return parsed; | ||
} | ||
|
||
private _parseMethod(expression: string): Signature|undefined { | ||
const m = expression.match(/(\w*)\((.*)\)/); | ||
if (m) { | ||
const sig: Signature = {method: m[1], static: true}; | ||
if (m[2].trim()) { | ||
// replace escaped commas with comma entity, split on un-escaped commas | ||
const args = m[2].replace(/\\,/g, ',').split(','); | ||
return this._parseArgs(args, sig); | ||
} else { | ||
sig.args = []; | ||
return sig; | ||
} | ||
} | ||
} | ||
|
||
private _parseArgs(argList: string[], sig: Signature): Signature { | ||
sig.args = argList.map((rawArg) => { | ||
const arg = this._parseArg(rawArg); | ||
if (!arg.literal) { | ||
sig.static = false; | ||
} | ||
return arg; | ||
}); | ||
return sig; | ||
} | ||
|
||
private _parseArg(rawArg: string): Argument { | ||
// clean up whitespace | ||
const arg = | ||
rawArg | ||
.trim() | ||
// replace comma entity with comma | ||
.replace(/,/g, ',') | ||
// repair extra escape sequences; note only commas strictly need | ||
// escaping, but we allow any other char to be escaped since its | ||
// likely users will do this | ||
.replace(/\\(.)/g, '\$1'); | ||
// basic argument descriptor | ||
const a: Argument = {name: arg}; | ||
// detect literal value (must be String or Number) | ||
let fc = arg[0]; | ||
if (fc >= '0' && fc <= '9') { | ||
fc = '#'; | ||
} | ||
switch (fc) { | ||
case '\'': | ||
case '"': | ||
a.value = arg.slice(1, -1); | ||
a.literal = true; | ||
break; | ||
case '#': | ||
a.value = Number(arg); | ||
a.literal = true; | ||
break; | ||
default: | ||
// no-op | ||
} | ||
// if not literal, look for structured path | ||
if (!a.literal) { | ||
// detect structured path (has dots) | ||
a.structured = arg.indexOf('.') > 0; | ||
if (a.structured) { | ||
a.wildcard = (arg.slice(-2) === '.*'); | ||
if (a.wildcard) { | ||
a.name = arg.slice(0, -2); | ||
} | ||
} | ||
} | ||
return a; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
import {Document} from 'polymer-analyzer/lib/model/model'; | ||
import {Warning} from 'polymer-analyzer/lib/warning/warning'; | ||
import {Rule} from '../rule'; | ||
|
||
export class AnalyzerWarnings implements Rule { | ||
public async check(document: Document): Promise<Warning[]> { | ||
const warnings: Warning[] = document.getWarnings(); | ||
return warnings; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend instead making this:
type ParsedExpression = Computed | Literal | Reference
And make each of those three types an interface with a string literal
type
field. That way we can separate out the fields and type safety will help us in a lot of ways.This is how we're typing estree, and it's paid off hugely. It lets you switch over
expression.type
.. lots of stuff.