Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/analyzer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

<!-- ## Unreleased -->
## Unreleased
* Typings change: `ParsedDocument#astNode` had the type `any`. It now has a
more strict type of `{} | null | undefined`. If this breaks downstream code,
that code should probably use a more specific type of `ParsedDocument`, or
`Document<MoreSpecificParsedDocType>`.
<!-- Add new, unreleased changes here. -->

## [3.0.0-pre.23] - 2018-04-17
Expand Down
3 changes: 2 additions & 1 deletion packages/analyzer/src/core/analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ export interface ForkOptions { urlLoader?: UrlLoader; }

export class NoKnownParserError extends Error {};

export type ScannerTable = Map<string, Scanner<ParsedDocument, {}, {}>[]>;
export type ScannerTable =
Map<string, Scanner<ParsedDocument, {}|null|undefined, {}>[]>;
export type LazyEdgeMap = Map<ResolvedUrl, PackageRelativeUrl[]>;

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/analyzer/src/html/html-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export class ParsedHtmlDocument extends ParsedDocument<ASTNode, HtmlVisitor> {

// We can modify these, as they don't escape this method.
const mutableDocuments = clone(immutableDocuments);
const selfClone = mutableDocuments.shift()!;
const selfClone: this = mutableDocuments.shift()! as this;

// We must handle documents that are inline to us but mutated here.
// If they're not inline us, we'll pass them along to our child documents
Expand Down
4 changes: 3 additions & 1 deletion packages/analyzer/src/parser/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import {ResolvedUrl} from '../model/url';
* @template AstNode The AST type of the document.
* @template Visitor The type of the visitors that can walk the document.
*/
export abstract class ParsedDocument<AstNode = any, Visitor = any> {
export abstract class ParsedDocument<
AstNode = {} | null | undefined,
Visitor = {}> {
abstract type: string;
url: ResolvedUrl;
baseUrl: ResolvedUrl;
Expand Down
8 changes: 4 additions & 4 deletions packages/analyzer/src/test/core/analyzer_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -655,10 +655,10 @@ suite('Analyzer', () => {
const document = new HtmlParser().parse(
contents, resolvedUrl`test.html`, new PackageUrlResolver());
const context = await getContext(analyzer);
const features =
(await context['_getScannedFeatures'](document))
.features.filter((e) => e instanceof ScannedImport) as
ScannedImport[];
const features = (await context['_getScannedFeatures'](document))
.features.filter(
(e: ScannedFeature) => e instanceof
ScannedImport) as ScannedImport[];
assert.equal(features.length, 1);
assert.equal(features[0].type, 'css-import');
assert.equal(features[0].url, 'bar.css' as FileRelativeUrl);
Expand Down
42 changes: 42 additions & 0 deletions packages/bundler/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "test:watch",
"isBackground": true,
"presentation": {
"echo": false,
"reveal": "always",
"focus": false,
"panel": "dedicated"
},
"group": {
"kind": "test",
"isDefault": true
},
"promptOnClose": false,
"problemMatcher": {
"fileLocation": [
"relative",
"${workspaceRoot}/src"
],
"background": {
"beginsPattern": "tsc-then: Running",
"endsPattern": "tsc-then: command finished"
},
"pattern": [
{
"regexp": "^ (\\d+)\\) ((\\w+).*)",
"message": 2,
"file": 3,
"line": 1,
"column": 1
}
],
"applyTo": "allDocuments",
"severity": "error"
}
}
]
}
4 changes: 3 additions & 1 deletion packages/bundler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

<!-- ## Unreleased -->
## Unreleased
- Bundled documents now have a `language` field. It will be `html` when the ast
node is an HTML Parse5 node, and `js` when the ast node is a JS babel node.
<!-- Add new, unreleased changes here. -->

## 4.0.0-pre.5 - 2018-04-17
Expand Down
21 changes: 21 additions & 0 deletions packages/bundler/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion packages/bundler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"mocha": "^2.2.4",
"rewire": "^2.5.2",
"source-map-support": "^0.4.2",
"tsc-then": "^1.1.0",
"tslint": "^3.15.1",
"typescript": "^2.2.0",
"typings": "^1.3.2"
Expand All @@ -56,7 +57,8 @@
"build": "tsc",
"format": "find src | grep '\\.js$\\|\\.ts$' | xargs ./node_modules/.bin/clang-format --style=file -i",
"test": "npm run build && tslint -c tslint.json src/*.ts src/**/*.ts && mocha",
"test:unit": "mocha"
"test:unit": "mocha",
"test:watch": "tsc-then -- mocha"
},
"author": "The Polymer Project Authors",
"license": "BSD-3-Clause",
Expand Down
22 changes: 21 additions & 1 deletion packages/bundler/src/analyzer-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import {Analysis, Document} from 'polymer-analyzer';
import {Analysis, Document, ParsedHtmlDocument, ParsedJavaScriptDocument} from 'polymer-analyzer';

export function getAnalysisDocument(analysis: Analysis, url: string): Document {
const result = analysis.getDocument(url);
Expand All @@ -24,3 +24,23 @@ export function getAnalysisDocument(analysis: Analysis, url: string): Document {
}
throw new Error(`Unable to get document ${url}`);
}

export function assertIsHtmlDocument(doc: Document):
Document<ParsedHtmlDocument> {
if (doc.kinds.has('html-document')) {
return doc as Document<ParsedHtmlDocument>;
} else {
throw new Error(
`Document wasn't an HTML document, it's a: ${[...doc.kinds]}`);
}
}

export function assertIsJsDocument(doc: Document):
Document<ParsedJavaScriptDocument> {
if (doc.kinds.has('js-document')) {
return doc as Document<ParsedJavaScriptDocument>;
} else {
throw new Error(
`Document wasn't an JS document, it's a: ${[...doc.kinds]}`);
}
}
9 changes: 4 additions & 5 deletions packages/bundler/src/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {getAnalysisDocument} from './analyzer-utils';
import * as bundleManifestLib from './bundle-manifest';
import {Bundle, BundleManifest, BundleStrategy, BundleUrlMapper} from './bundle-manifest';
import * as depsIndexLib from './deps-index';
import {BundledDocument, DocumentCollection} from './document-collection';
import {DocumentCollection} from './document-collection';
import {bundle as bundleEs6Module} from './es6-module-bundler';
import {reserveBundleModuleExportNames} from './es6-module-utils';
import {bundle as bundleHtmlFragment} from './html-bundler';
Expand Down Expand Up @@ -109,8 +109,8 @@ export class Bundler {
}

/**
* Analyze a URL using the given contents in place of what would otherwise
* have been loaded.
* Analyze an HTML URL using the given contents in place of what would
* otherwise have been loaded.
*/
async analyzeContents(
url: ResolvedUrl,
Expand Down Expand Up @@ -145,8 +145,7 @@ export class Bundler {
* @param manifest - The manifest that describes the bundles to be produced.
*/
async bundle(manifest: BundleManifest): Promise<BundleResult> {
const documents: DocumentCollection =
new Map<ResolvedUrl, BundledDocument>();
const documents = new DocumentCollection();
manifest = manifest.fork();

// Ensure exports of modules sharing the URL of their bundle have priority
Expand Down
40 changes: 37 additions & 3 deletions packages/bundler/src/document-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,48 @@
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import * as babel from 'babel-types';
import {ASTNode} from 'parse5';
import {ResolvedUrl} from 'polymer-analyzer';

export interface BundledDocument {
ast: ASTNode;
export interface BundledBaseDocument<Node> {
ast: Node;
content: string;
files: ResolvedUrl[];
}

export type BundledHtmlDocument = {
language: 'html'
} & BundledBaseDocument<ASTNode>;
export type BundledJsDocument = {
language: 'js'
} & BundledBaseDocument<babel.Node>;
export type BundledDocument = BundledHtmlDocument | BundledJsDocument;


/* A collection of documents, keyed by path */
export type DocumentCollection = Map<ResolvedUrl, BundledDocument>;
export class DocumentCollection extends Map<ResolvedUrl, BundledDocument> {
getHtmlDoc(url: ResolvedUrl) {
const result = this.get(url);
if (result === undefined) {
return undefined;
}
if (result.language !== 'html') {
throw new Error(
`Expected url ${url} to be html but it was ${result.language}`);
}
return result;
}

getJsDoc(url: ResolvedUrl) {
const result = this.get(url);
if (result === undefined) {
return undefined;
}
if (result.language !== 'js') {
throw new Error(
`Expected url ${url} to be js but it was ${result.language}`);
}
return result;
}
}
11 changes: 6 additions & 5 deletions packages/bundler/src/es6-module-bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ import generate from 'babel-generator';
import * as babel from 'babel-types';
import {ResolvedUrl} from 'polymer-analyzer';

import {getAnalysisDocument} from './analyzer-utils';
import {assertIsJsDocument, getAnalysisDocument} from './analyzer-utils';
import {AssignedBundle, BundleManifest} from './bundle-manifest';
import {Bundler} from './bundler';
import {BundledDocument} from './document-collection';
import {BundledJsDocument} from './document-collection';
import {getModuleExportNames, getOrSetBundleModuleExportName} from './es6-module-utils';
import {Es6Rewriter} from './es6-rewriter';
import {ensureLeadingDot, stripUrlFileSearchAndHash} from './url-utils';
Expand All @@ -28,7 +28,7 @@ import {ensureLeadingDot, stripUrlFileSearchAndHash} from './url-utils';
*/
export async function bundle(
bundler: Bundler, manifest: BundleManifest, url: ResolvedUrl):
Promise<BundledDocument> {
Promise<BundledJsDocument> {
const bundle = manifest.bundles.get(url);
if (!bundle) {
throw new Error(`No bundle found in manifest for url ${url}.`);
Expand All @@ -38,9 +38,10 @@ export async function bundle(
await prepareBundleModule(bundler, manifest, assignedBundle);
const es6Rewriter = new Es6Rewriter(bundler, manifest, assignedBundle);
const {code: rolledUpCode} = await es6Rewriter.rollup(url, generatedCode);
const document =
await bundler.analyzeContents(assignedBundle.url, rolledUpCode);
const document = assertIsJsDocument(
await bundler.analyzeContents(assignedBundle.url, rolledUpCode));
return {
language: 'js',
ast: document.parsedDocument.ast,
content: document.parsedDocument.contents,
files: [...assignedBundle.bundle.files]
Expand Down
4 changes: 2 additions & 2 deletions packages/bundler/src/es6-rewriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import * as clone from 'clone';
import {FileRelativeUrl, PackageRelativeUrl, ResolvedUrl} from 'polymer-analyzer';
import {rollup} from 'rollup';

import {getAnalysisDocument} from './analyzer-utils';
import {assertIsJsDocument, getAnalysisDocument} from './analyzer-utils';
import {serialize} from './babel-utils';
import {AssignedBundle, BundleManifest} from './bundle-manifest';
import {Bundler} from './bundler';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class Es6Rewriter {
appendUrlPath(url, '_inline_es6_module.js');
const rolledUpDocument = await this.bundler.analyzeContents(
rolledUpUrl as ResolvedUrl, rolledUpCode);
const babelFile = rolledUpDocument.parsedDocument.ast;
const babelFile = assertIsJsDocument(rolledUpDocument).parsedDocument.ast;
this._rewriteImportStatements(url, babelFile);
this._deduplicateImportStatements(babelFile);
const {code: rewrittenCode} = serialize(babelFile);
Expand Down
Loading