Skip to content
This repository has been archived by the owner on May 14, 2021. It is now read-only.

Commit

Permalink
Merge 70fb264 into 18ba737
Browse files Browse the repository at this point in the history
  • Loading branch information
chinesedfan committed Nov 18, 2018
2 parents 18ba737 + 70fb264 commit bdbe084
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 23 deletions.
35 changes: 17 additions & 18 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
const path = require('path')
const parse = require('./parsers/index')
const isCausedBySubstitution = require('./utils/result').isCausedBySubstitution
const getCorrectColumn = require('./utils/result').getCorrectColumn

let inputId = 1

// Make sure that state for particular path will be cleaned before each run
// module may be kept in memory when used with vscode-stylelint
const taggedTemplateLocsMap = {}
const interpolationLinesMap = {}
const sourceMapsCorrections = {}
const errorWasThrown = {}
Expand All @@ -12,21 +16,6 @@ const DEFAULT_OPTIONS = {
importName: 'default'
}

function isCausedBySubstitution(warning, line, interpolationLines) {
return interpolationLines.some(({ start, end }) => {
if (line > start && line < end) {
// Inner interpolation lines must be
return true
} else if (line === start) {
return ['value-list-max-empty-lines', 'comment-empty-line-before'].indexOf(warning.rule) >= 0
} else if (line === end) {
return ['comment-empty-line-before', 'indentation'].indexOf(warning.rule) >= 0
} else {
return false
}
})
}

module.exports = options => ({
// Get string for stylelint to lint
code(input, filepath) {
Expand All @@ -39,16 +28,20 @@ module.exports = options => ({
}

try {
delete errorWasThrown[absolutePath]
const { extractedCSS, interpolationLines, sourceMap } = parse(
const { extractedCSS, interpolationLines, taggedTemplateLocs, sourceMap } = parse(
input,
absolutePath,
Object.assign({}, DEFAULT_OPTIONS, options)
)
// Save `loc` of template literals
taggedTemplateLocsMap[absolutePath] = taggedTemplateLocs
// Save dummy interpolation lines
interpolationLinesMap[absolutePath] = interpolationLines
// Save source location
sourceMapsCorrections[absolutePath] = sourceMap
// Clean errors
delete errorWasThrown[absolutePath]

return extractedCSS
} catch (e) {
// Always save the error
Expand Down Expand Up @@ -86,6 +79,7 @@ module.exports = options => ({
})
}
}
const taggedTemplateLocs = taggedTemplateLocsMap[filepath] || []
const interpolationLines = interpolationLinesMap[filepath] || []
const lineCorrection = sourceMapsCorrections[filepath]
const warnings = stylelintResult.warnings
Expand All @@ -99,7 +93,12 @@ module.exports = options => ({
// Replace "brace" with "backtick" in warnings, e.g.
// "Unexpected empty line before closing backtick" (instead of "brace")
text: warning.text.replace(/brace/, 'backtick'),
line: lineCorrection[warning.line] || warning.line
line: lineCorrection[warning.line] || warning.line,
column: getCorrectColumn(
taggedTemplateLocs,
lineCorrection[warning.line] || warning.line,
warning.column
)
})
)

Expand Down
7 changes: 7 additions & 0 deletions src/parsers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const processStyledComponentsFile = (ast, absolutePath, options) => {
createGlobalStyle: 'createGlobalStyle'
}
let sourceMap = {}
const taggedTemplateLocs = []
const interpolationLines = []
traverse(ast, {
noScope: true,
Expand Down Expand Up @@ -82,6 +83,11 @@ const processStyledComponentsFile = (ast, absolutePath, options) => {
sourceMap,
getSourceMap(extractedCSS.join('\n'), wrappedContent, processedNode.quasi.loc.start.line)
)
// Save `loc` of template literals
taggedTemplateLocs.push({
wrappedOffset: wrappedContent.indexOf(fixedContent),
start: node.quasi.loc.start
})
// Save dummy interpolation lines
node.quasi.expressions.forEach((expression, i) => {
interpolationLines.push({
Expand All @@ -100,6 +106,7 @@ const processStyledComponentsFile = (ast, absolutePath, options) => {

return {
extractedCSS: extractedCSS.join('\n'),
taggedTemplateLocs,
interpolationLines,
sourceMap
}
Expand Down
30 changes: 30 additions & 0 deletions src/utils/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
exports.isCausedBySubstitution = (warning, line, interpolationLines) =>
interpolationLines.some(({ start, end }) => {
if (line > start && line < end) {
// Inner interpolation lines must be
return true
} else if (line === start) {
return ['value-list-max-empty-lines', 'comment-empty-line-before'].indexOf(warning.rule) >= 0
} else if (line === end) {
return ['comment-empty-line-before', 'indentation'].indexOf(warning.rule) >= 0
} else {
return false
}
})

exports.getCorrectColumn = (taggedTemplateLocs, line, column) => {
let c = column

// Not consider multiple tagged literals exsit in the same line,
// so we only add column offset of the first one
taggedTemplateLocs.some(loc => {
if (line === loc.start.line) {
// Start column contains the back quote, so we need inscrese 1
c += loc.start.column + 1 - loc.wrappedOffset
return true
}
return false
})

return c
}
3 changes: 3 additions & 0 deletions test/fixtures/hard/source-maps.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ const Button6 = styled.button`
`}
display: block;
`

// ⚠️ UNKNOWN PROPERTY at 42:31 ⚠️
const Button7 = styled.button`unknown: blue;`
16 changes: 11 additions & 5 deletions test/hard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const path = require('path')
const processor = path.join(__dirname, '../lib/index.js')
const rules = {
'block-no-empty': true,
'property-no-unknown': true,
indentation: 2
indentation: 2,
'property-no-unknown': true
}

describe('hard', () => {
Expand Down Expand Up @@ -103,16 +103,17 @@ describe('hard', () => {
expect(data.errored).toEqual(true)
})

it('should have five warning', () => {
expect(data.results[0].warnings.length).toEqual(5)
it('should have six warnings', () => {
expect(data.results[0].warnings.length).toEqual(6)
})

it('should have four warnings about indentation', () => {
it('should have five warnings about indentation', () => {
expect(data.results[0].warnings[0].rule).toEqual('indentation')
expect(data.results[0].warnings[1].rule).toEqual('indentation')
expect(data.results[0].warnings[2].rule).toEqual('indentation')
expect(data.results[0].warnings[3].rule).toEqual('indentation')
expect(data.results[0].warnings[4].rule).toEqual('indentation')
expect(data.results[0].warnings[5].rule).toEqual('property-no-unknown')
})

it('should have a warning in line 5', () => {
Expand All @@ -134,6 +135,11 @@ describe('hard', () => {
it('should have a warning in line 35', () => {
expect(data.results[0].warnings[4].line).toEqual(35)
})

it('should have a warning in line 42, column 31', () => {
expect(data.results[0].warnings[5].line).toEqual(42)
expect(data.results[0].warnings[5].column).toEqual(31)
})
})

describe('js style comments', () => {
Expand Down
35 changes: 35 additions & 0 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const isStylelintComment = require('../lib/utils/general').isStylelintComment
const fixIndentation = require('../lib/utils/general').fixIndentation
const extrapolateShortenedCommand = require('../lib/utils/general').extrapolateShortenedCommand
const removeBaseIndentation = require('../lib/utils/general').removeBaseIndentation
const isCausedBySubstitution = require('../lib/utils/result').isCausedBySubstitution
const getCorrectColumn = require('../lib/utils/result').getCorrectColumn

const mockLoc = (startLine, endLine) => ({
start: {
Expand Down Expand Up @@ -620,4 +622,37 @@ html {
expect(fn(inputCss)).toBe(expectedOutput)
})
})

describe('isCausedBySubstitution', () => {
const fn = isCausedBySubstitution
const interpolationLines = [{ start: 2, end: 4 }, { start: 5, end: 5 }]
it("returns true if real warning line is between some interpolation's start and end", () => {
expect(fn({ rule: 'any rule' }, 3, interpolationLines)).toEqual(true)
})
it("returns false if real warning line is beyond any interpolation's start and end", () => {
expect(fn({ rule: 'any rule' }, 1, interpolationLines)).toEqual(false)
})
it("checks warning rule if real warning line is at some interpolations' start", () => {
expect(fn({ rule: 'comment-empty-line-before' }, 2, interpolationLines)).toEqual(true)
expect(fn({ rule: 'another rule' }, 2, interpolationLines)).toEqual(false)
})
it("checks warning rule if real warning line is at some interpolations' end", () => {
expect(fn({ rule: 'comment-empty-line-before' }, 4, interpolationLines)).toEqual(true)
expect(fn({ rule: 'another rule' }, 4, interpolationLines)).toEqual(false)
})
})

describe('getCorrectColumn', () => {
const fn = getCorrectColumn
const taggedTemplateLocs = [
{ wrappedOffset: 3, start: { line: 1, column: 6 } },
{ wrappedOffset: 12, start: { line: 5, column: 39 } }
]
it('returns identically if the line is not any first line of tagged templates', () => {
expect(fn(taggedTemplateLocs, 4, 1)).toEqual(1)
})
it('returns correctly if the line is some first line of tagged templates', () => {
expect(fn(taggedTemplateLocs, 5, 23)).toEqual(51)
})
})
})

0 comments on commit bdbe084

Please sign in to comment.