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

Compile clean with strict initialization #857

Merged
merged 3 commits into from
Jan 31, 2018
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: 3 additions & 3 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"temp": "^0.8.3",
"tsc-then": "^1.0.1",
"tslint": "^4.1.1",
"typescript": "^2.6.1",
"typescript": "^2.7.1",
"typescript-json-schema": "^0.19.0"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/analysis-format/generate-analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ function serializeElementMixin(
function serializePolymerBehaviorAsElementMixin(
behavior: ResolvedPolymerBehavior, urlResolver: UrlResolver): ElementMixin {
const metadata = serializeElementLike(behavior, urlResolver) as ElementMixin;
metadata.name = behavior.className;
metadata.name = behavior.className!;
metadata.privacy = behavior.privacy;
if (behavior.mixins.length > 0) {
metadata.mixins = behavior.mixins.map((m) => m.identifier);
Expand Down
14 changes: 7 additions & 7 deletions src/core/analysis-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export class AnalysisContext {
options.scanners || AnalysisContext.getDefaultScanners(this._lazyEdges);
this._cache = cache || new AnalysisCache();
this._generation = generation || 0;
this._analysisComplete = Promise.resolve();
}

/**
Expand Down Expand Up @@ -431,12 +432,11 @@ export class AnalysisContext {
};
try {
const parsedDoc = this._parseContents(
feature.type,
feature.contents,
containingDocument.url,
{locationOffset, astNode: feature.astNode});
// Inline documents inherit the base url of their containers.
parsedDoc.baseUrl = containingDocument.document.baseUrl;
feature.type, feature.contents, containingDocument.url, {
locationOffset,
astNode: feature.astNode,
baseUrl: containingDocument.document.baseUrl
});
const scannedDoc = await this._scanDocument(
parsedDoc, feature.attachedComment, containingDocument.document);

Expand Down Expand Up @@ -494,7 +494,7 @@ export class AnalysisContext {
*/
private _parseContents(
type: string, contents: string, url: ResolvedUrl,
inlineInfo?: InlineDocInfo<any>): ParsedDocument {
inlineInfo?: InlineDocInfo): ParsedDocument {
const parser = this.parsers.get(type);
if (parser == null) {
throw new NoKnownParserError(`No parser for for file type ${type}`);
Expand Down
4 changes: 2 additions & 2 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export function isPathInside(directory: string, filePath: string): boolean {

export class Deferred<T> {
promise: Promise<T>;
resolve: (result: T) => void;
reject: (error: Error) => void;
resolve!: (result: T) => void;
reject!: (error: Error) => void;
resolved = false;
rejected = false;
error: any;
Expand Down
8 changes: 2 additions & 6 deletions src/css/css-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,14 @@
import * as shady from 'shady-css-parser';

import {SourceRange} from '../model/model';
import {Options, ParsedDocument, StringifyOptions} from '../parser/document';
import {ParsedDocument, StringifyOptions} from '../parser/document';

import cssbeautify = require('cssbeautify');

export interface Visitor { visit(node: shady.Node): void; }

export class ParsedCssDocument extends ParsedDocument<shady.Node, Visitor> {
type = 'css';

constructor(from: Options<shady.Node>) {
super(from);
}
readonly type = 'css';

visit(visitors: Visitor[]) {
for (const node of this) {
Expand Down
3 changes: 2 additions & 1 deletion src/css/css-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ export class CssParser implements Parser<ParsedCssDocument> {

parse(
contents: string, url: ResolvedUrl, _urlResolver: UrlResolver,
inlineInfo?: InlineDocInfo<any>): ParsedCssDocument {
inlineInfo?: InlineDocInfo): ParsedCssDocument {
const ast = this._parser.parse(contents);
const isInline = !!inlineInfo;
inlineInfo = inlineInfo || {};
return new ParsedCssDocument({
url,
baseUrl: inlineInfo.baseUrl,
contents,
ast,
locationOffset: inlineInfo.locationOffset,
Expand Down
6 changes: 1 addition & 5 deletions src/html/html-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as parse5 from 'parse5';
import {ASTNode} from 'parse5';

import {SourceRange} from '../model/model';
import {Options, ParsedDocument, StringifyOptions} from '../parser/document';
import {ParsedDocument, StringifyOptions} from '../parser/document';

/**
* The ASTs of the HTML elements needed to represent Polymer elements.
Expand All @@ -29,10 +29,6 @@ export interface HtmlVisitor { (node: ASTNode): void; }
export class ParsedHtmlDocument extends ParsedDocument<ASTNode, HtmlVisitor> {
type = 'html';

constructor(from: Options<ASTNode>) {
super(from);
}

visit(visitors: HtmlVisitor[]) {
dom5.nodeWalk(this.ast, (node) => {
visitors.forEach((visitor) => visitor(node));
Expand Down
20 changes: 12 additions & 8 deletions src/html/html-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class HtmlParser implements Parser<ParsedHtmlDocument> {
*/
parse(
contents: string, url: ResolvedUrl, urlResolver: UrlResolver,
inlineInfo?: InlineDocInfo<any>): ParsedHtmlDocument {
inlineInfo?: InlineDocInfo): ParsedHtmlDocument {
const ast = parseHtml(contents, {locationInfo: true});

// There should be at most one <base> tag and it must be inside <head> tag.
Expand All @@ -42,16 +42,20 @@ export class HtmlParser implements Parser<ParsedHtmlDocument> {
p.hasTagName('base'),
p.hasAttr('href')));

let baseUrl;
const isInline = !!inlineInfo;
inlineInfo = inlineInfo || {};

let baseUrl: ResolvedUrl =
inlineInfo.baseUrl !== undefined ? inlineInfo.baseUrl : url;
if (baseTag) {
const baseHref = getAttribute(baseTag, 'href')! as FileRelativeUrl;
baseUrl = urlResolver.resolve(url, baseHref, undefined);
} else {
baseUrl = url;
const baseTagHref = getAttribute(baseTag, 'href')! as FileRelativeUrl;
const resolvedBaseTagHref =
urlResolver.resolve(url, baseTagHref, undefined);
if (resolvedBaseTagHref !== undefined) {
baseUrl = resolvedBaseTagHref;
}
}

const isInline = !!inlineInfo;
inlineInfo = inlineInfo || {};
return new ParsedHtmlDocument({
url,
baseUrl,
Expand Down
4 changes: 2 additions & 2 deletions src/html/html-script-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ import {FileRelativeUrl} from '../model/url';
* represents a script tag with a `src` attribute as an import, so that the
* analyzer loads and parses the referenced document.
*/
export class ScriptTagImport extends Import { type: 'html-script'; }
export class ScriptTagImport extends Import { readonly type = 'html-script'; }

/**
* A synthetic import that provides the document containing the script tag to
* the javascript document defined/referenced by the script tag.
*/
export class ScriptTagBackReferenceImport extends Import {
type: 'html-script-back-reference';
readonly type = 'html-script-back-reference';
}

export class ScannedScriptTagImport extends ScannedImport {
Expand Down
4 changes: 2 additions & 2 deletions src/javascript/javascript-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export interface Options extends ParsedDocumentOptions<Program> {
}

export class JavaScriptDocument extends ParsedDocument<Node, Visitor> {
type = 'js';
readonly type = 'js';
private visitorSkips = new Map<Visitor, SkipRecord>();
ast: Program;
ast!: Program; // assigned in super, this type is just a refinement.

/**
* How the js document was parsed. If 'module' then the source code is
Expand Down
10 changes: 6 additions & 4 deletions src/javascript/javascript-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ const baseParseOptions: babylon.BabylonOptions = {
(baseParseOptions as any)['ranges'] = true;

export class JavaScriptParser implements Parser<JavaScriptDocument> {
sourceType: SourceType;
readonly sourceType?: SourceType;

parse(
contents: string, url: ResolvedUrl, _urlResolver: UrlResolver,
inlineInfo?: InlineDocInfo<any>): JavaScriptDocument {
inlineInfo?: InlineDocInfo): JavaScriptDocument {
const isInline = !!inlineInfo;
inlineInfo = inlineInfo || {};
const result = parseJs(
Expand All @@ -58,6 +58,7 @@ export class JavaScriptParser implements Parser<JavaScriptDocument> {
const minimalDocument = new JavaScriptDocument({
url,
contents,
baseUrl: inlineInfo.baseUrl,
ast: null as any,
locationOffset: inlineInfo.locationOffset,
astNode: inlineInfo.astNode,
Expand All @@ -71,6 +72,7 @@ export class JavaScriptParser implements Parser<JavaScriptDocument> {
return new JavaScriptDocument({
url,
contents,
baseUrl: inlineInfo.baseUrl,
ast: result.program,
locationOffset: inlineInfo.locationOffset,
astNode: inlineInfo.astNode,
Expand All @@ -81,11 +83,11 @@ export class JavaScriptParser implements Parser<JavaScriptDocument> {
}

export class JavaScriptModuleParser extends JavaScriptParser {
sourceType: SourceType = 'module';
readonly sourceType: SourceType = 'module';
}

export class JavaScriptScriptParser extends JavaScriptParser {
sourceType: SourceType = 'script';
readonly sourceType: SourceType = 'script';
}

export type ParseResult = {
Expand Down
8 changes: 2 additions & 6 deletions src/json/json-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

import {SourceRange} from '../model/model';
import {Options, ParsedDocument} from '../parser/document';
import {ParsedDocument} from '../parser/document';

export type Json = JsonObject|JsonArray|number|string|boolean|null;
export interface JsonObject { [key: string]: Json; }
Expand All @@ -22,11 +22,7 @@ export interface JsonArray extends Array<Json> {}
export interface Visitor { visit(node: Json): void; }

export class ParsedJsonDocument extends ParsedDocument<Json, Visitor> {
type = 'json';

constructor(from: Options<Json>) {
super(from);
}
readonly type = 'json';

visit(visitors: Visitor[]) {
this._visit(this.ast, visitors);
Expand Down
3 changes: 2 additions & 1 deletion src/json/json-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import {ParsedJsonDocument} from './json-document';
export class JsonParser implements Parser<ParsedJsonDocument> {
parse(
contents: string, url: ResolvedUrl, _urlResolver: UrlResolver,
inlineDocInfo: InlineDocInfo<any>): ParsedJsonDocument {
inlineDocInfo: InlineDocInfo): ParsedJsonDocument {
const isInline = !!inlineDocInfo;
inlineDocInfo = inlineDocInfo || {};
return new ParsedJsonDocument({
url,
baseUrl: inlineDocInfo.baseUrl,
contents,
ast: JSON.parse(contents),
locationOffset: inlineDocInfo.locationOffset,
Expand Down
4 changes: 2 additions & 2 deletions src/model/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class ScannedDocument {
get sourceRange() {
return this.document.sourceRange;
}
get astNode(): AstNodeWithLanguage|null {
get astNode(): AstNodeWithLanguage|undefined {
return this.document.astNode;
}

Expand Down Expand Up @@ -157,7 +157,7 @@ export class Document<ParsedType extends ParsedDocument = ParsedDocument>
return this._scannedDocument.sourceRange;
}

get astNode(): AstNodeWithLanguage|null {
get astNode(): AstNodeWithLanguage|undefined {
return this._scannedDocument.astNode;
}

Expand Down
12 changes: 6 additions & 6 deletions src/model/element-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export abstract class ScannedElementBase implements Resolvable {
demos: Demo[] = [];
events: Map<string, ScannedEvent> = new Map();
sourceRange: SourceRange|undefined;
staticMethods: Map<string, ScannedMethod>;
methods: Map<string, ScannedMethod>;
astNode: babel.Node|null;
staticMethods: Map<string, ScannedMethod> = new Map();
methods: Map<string, ScannedMethod> = new Map();
astNode: babel.Node|null = null;
warnings: Warning[] = [];
jsdoc?: jsdoc.Annotation;
'slots': Slot[] = [];
mixins: ScannedReference[] = [];
privacy: Privacy;
privacy!: Privacy;
abstract: boolean = false;
superClass?: ScannedReference = undefined;

Expand Down Expand Up @@ -145,8 +145,8 @@ export abstract class ElementBase extends Class implements Feature {
// Initialization of these attributes is kinda awkward, as they're part
// of the inheritance system. See `inheritFrom` below which *may* be
// called by our superclass, but may not be.
this.attributes = this.attributes || new Map();
this.events = this.events || new Map();
this.attributes = (this as any).attributes || new Map();
this.events = (this as any).events || new Map();

if (attributes !== undefined) {
this._overwriteInherited(this.attributes, attributes, undefined, true);
Expand Down
1 change: 1 addition & 0 deletions src/model/element-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,6 @@ export class ElementMixin extends ElementBase implements Feature {
constructor(init: ElementMixinInit, document: Document) {
super(init, document);
this.kinds.add('element-mixin');
this.name = init.name;
}
}
3 changes: 1 addition & 2 deletions src/model/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import {Document} from './document';
import {ElementBase, ElementBaseInit, ScannedElementBase} from './element-base';
import {Feature, Privacy} from './feature';
import {Feature} from './feature';
import {ScannedReference} from './reference';

export {Visitor} from '../javascript/estree-visitor';
Expand All @@ -26,7 +26,6 @@ export class ScannedElement extends ScannedElementBase {
return this.className;
}
superClass?: ScannedReference;
privacy: Privacy;

/**
* For customized built-in elements, the tagname of the superClass.
Expand Down
6 changes: 4 additions & 2 deletions src/model/inline-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ import {ScannedFeature} from './feature';
import {unsafeAsMutable} from './immutable';
import {Resolvable} from './resolvable';
import {LocationOffset, SourceRange} from './source-range';
import {ResolvedUrl} from './url';
import {Warning} from './warning';

export interface InlineDocInfo<AstNode> {
astNode?: AstNode;
export interface InlineDocInfo {
astNode?: AstNodeWithLanguage;
locationOffset?: LocationOffset;
baseUrl?: ResolvedUrl;
}

export type AstNodeWithLanguage = {
Expand Down
1 change: 1 addition & 0 deletions src/model/reference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class ScannedReference extends ScannedFeature implements Resolvable {
identifier: string, sourceRange: SourceRange, astNode?: any,
description?: string, jsdoc?: Annotation, warnings?: Warning[]) {
super(sourceRange, astNode, description, jsdoc, warnings);
this.sourceRange = sourceRange;
this.identifier = identifier;
}

Expand Down
Loading