Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
6 changes: 4 additions & 2 deletions 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 Expand Up @@ -183,7 +185,7 @@ export class UnparsableParsedDocument extends ParsedDocument {
type: string = 'unparsable';
constructor(url: ResolvedUrl, contents: string) {
super({
ast: null,
ast: null as any,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this safe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out it wasn't necessary. Removed.

url,
baseUrl: url,
astNode: undefined,
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