More cleanup and a possible fix for #29

This commit is contained in:
dcodeIO
2018-02-16 11:55:13 +01:00
parent f729444320
commit 3d7e8b2b7a
17 changed files with 1038 additions and 680 deletions

View File

@ -1644,7 +1644,9 @@ export class WhileStatement extends Statement {
/** Cached unused modifiers for reuse. */
var reusableModifiers: Modifier[] | null = null;
export function setReusableModifiers(modifiers: Modifier[]) {
export function setReusableModifiers(
modifiers: Modifier[]
): void {
reusableModifiers = modifiers;
}
@ -1660,16 +1662,22 @@ export function createModifiers(): Modifier[] {
return ret;
}
/** Adds a modifier to a modifiers array. Creates and returns a new array if `null`. */
export function addModifier(modifier: Modifier, modifiers: Modifier[] | null): Modifier[] {
/** Adds a modifier to a set of modifiers. Creates a new set if `null`. */
export function addModifier(
modifier: Modifier,
modifiers: Modifier[] | null
): Modifier[] {
if (modifiers == null)
modifiers = createModifiers();
modifiers.push(modifier);
return modifiers;
}
/** Gets a specific modifier from the specified array of modifiers. */
export function getModifier(kind: ModifierKind, modifiers: Modifier[] | null): Modifier | null {
/** Gets a specific modifier from the specified set of modifiers. */
export function getModifier(
kind: ModifierKind,
modifiers: Modifier[] | null
): Modifier | null {
if (modifiers)
for (var i = 0, k = modifiers.length; i < k; ++i)
if (modifiers[i].modifierKind == kind)
@ -1677,13 +1685,19 @@ export function getModifier(kind: ModifierKind, modifiers: Modifier[] | null): M
return null;
}
/** Tests whether a specific modifier exists in the specified array of modifiers. */
export function hasModifier(kind: ModifierKind, modifiers: Modifier[] | null): bool {
/** Tests whether a modifier exists in the specified set of modifiers. */
export function hasModifier(
kind: ModifierKind,
modifiers: Modifier[] | null
): bool {
return getModifier(kind, modifiers) != null;
}
/** Gets a specific decorator within the specified decorators, if present. */
export function getFirstDecorator(name: string, decorators: Decorator[] | null): Decorator | null {
/** Gets the first decorator by name within at set of decorators, if present. */
export function getFirstDecorator(
name: string,
decorators: Decorator[] | null
): Decorator | null {
if (decorators)
for (var i = 0, k = decorators.length; i < k; ++i) {
var decorator = decorators[i];
@ -1695,12 +1709,18 @@ export function getFirstDecorator(name: string, decorators: Decorator[] | null):
}
/** Tests if a specific decorator is present within the specified decorators. */
export function hasDecorator(name: string, decorators: Decorator[] | null): bool {
export function hasDecorator(
name: string,
decorators: Decorator[] | null
): bool {
return getFirstDecorator(name, decorators) != null;
}
/** Mangles a declaration's name to an internal name. */
export function mangleInternalName(declaration: DeclarationStatement, asGlobal: bool = false): string {
export function mangleInternalName(
declaration: DeclarationStatement,
asGlobal: bool = false
): string {
var name = declaration.name.text;
var parent = declaration.parent;
if (!parent)
@ -1720,18 +1740,26 @@ export function mangleInternalName(declaration: DeclarationStatement, asGlobal:
}
/** Mangles an external to an internal path. */
export function mangleInternalPath(path: string): string {
export function mangleInternalPath(
path: string
): string {
if (path.endsWith(".ts"))
path = path.substring(0, path.length - 3);
return path;
}
function setParent(nodes: Node[], parent: Node): void {
function setParent(
nodes: Node[],
parent: Node
): void {
for (var i = 0, k = nodes.length; i < k; ++i)
nodes[i].parent = parent;
}
function setParentOpt(nodes: (Node | null)[], parent: Node): void {
function setParentOpt(
nodes: (Node | null)[],
parent: Node
): void {
for (var i = 0, k = nodes.length; i < k; ++i) {
var node = nodes[i];
if (node)

View File

@ -122,10 +122,6 @@ import {
typesToNativeTypes
} from "./types";
import {
sb
} from "./util/sb";
/** Compilation target. */
export enum Target {
/** WebAssembly with 32-bit pointers. */

View File

@ -12,10 +12,6 @@ import {
isLineBreak
} from "./util/charcode";
import {
sb
} from "./util/sb";
export {
DiagnosticCode,
diagnosticCodeToString
@ -103,7 +99,7 @@ export function formatDiagnosticMessage(message: DiagnosticMessage, useColors: b
context = formatDiagnosticContext(message.range, useColors);
// general information
sb.length = 0;
var sb: string[] = [];
if (useColors) sb.push(diagnosticCategoryToColor(message.category));
sb.push(diagnosticCategoryToString(message.category));
if (useColors) sb.push(colorReset);
@ -141,10 +137,11 @@ export function formatDiagnosticContext(range: Range, useColors: bool = false):
start--;
while (end < len && !isLineBreak(text.charCodeAt(end)))
end++;
sb.length = 0;
sb.push("\n ");
sb.push(text.substring(start, end));
sb.push("\n ");
var sb: string[] = [
"\n ",
text.substring(start, end),
"\n "
];
while (start < range.start) {
sb.push(" ");
start++;

File diff suppressed because it is too large Load Diff

View File

@ -239,14 +239,7 @@ export class Parser extends DiagnosticEmitter {
/** Obtains the next file to parse. */
nextFile(): string | null {
if (this.backlog.length) {
var filename = this.backlog[0];
for (var i = 0, k = this.backlog.length - 1; i < k; ++i)
this.backlog[i] = this.backlog[i + 1];
this.backlog.length--;
return filename;
}
return null;
return this.backlog.length ? this.backlog.shift() : null;
}
/** Finishes parsing and returns the program. */

View File

@ -96,6 +96,7 @@ class QueuedExport {
class QueuedImport {
internalName: string;
referencedName: string;
referencedNameAlt: string;
declaration: ImportDeclaration;
}
@ -209,8 +210,14 @@ export class Program extends DiagnosticEmitter {
this.elements.set(queuedImport.internalName, element);
queuedImports.splice(i, 1);
} else {
this.error(DiagnosticCode.Module_0_has_no_exported_member_1, queuedImport.declaration.range, (<ImportStatement>queuedImport.declaration.parent).path.value, queuedImport.declaration.externalName.text);
++i;
element = this.tryResolveImport(queuedImport.referencedNameAlt, queuedExports);
if (element) {
this.elements.set(queuedImport.internalName, element);
queuedImports.splice(i, 1);
} else {
this.error(DiagnosticCode.Module_0_has_no_exported_member_1, queuedImport.declaration.range, (<ImportStatement>queuedImport.declaration.parent).path.value, queuedImport.declaration.externalName.text);
++i;
}
}
}
@ -756,38 +763,24 @@ export class Program extends DiagnosticEmitter {
var referencedName = internalPath + PATH_DELIMITER + declaration.externalName.text;
// resolve right away if the export exists
if (this.exports.has(referencedName)) {
this.elements.set(internalName, <Element>this.exports.get(referencedName));
// resolve right away if the exact export exists
var element: Element | null;
if (element = this.exports.get(referencedName)) {
this.elements.set(internalName, element);
return;
}
// walk already known queued exports
var seen = new Set<QueuedExport>();
var queuedExport: QueuedExport | null;
while (queuedExport = queuedExports.get(referencedName)) {
if (queuedExport.isReExport) {
if (this.exports.has(queuedExport.referencedName)) {
this.elements.set(internalName, <Element>this.exports.get(referencedName));
return;
}
referencedName = queuedExport.referencedName;
if (seen.has(queuedExport))
break;
seen.add(queuedExport);
} else {
if (this.elements.has(queuedExport.referencedName)) {
this.elements.set(internalName, <Element>this.elements.get(referencedName));
return;
}
break;
}
}
// otherwise queue it
var indexPart = PATH_DELIMITER + "index";
var queuedImport = new QueuedImport();
queuedImport.internalName = internalName;
queuedImport.referencedName = referencedName;
if (internalPath.endsWith(indexPart)) {
queuedImport.referencedName = referencedName; // try exact first
queuedImport.referencedNameAlt = internalPath.substring(0, internalPath.length - indexPart.length + 1) + declaration.externalName.text;
} else {
queuedImport.referencedName = referencedName; // try exact first
queuedImport.referencedNameAlt = internalPath + indexPart + PATH_DELIMITER + declaration.externalName.text;
}
queuedImport.declaration = declaration;
queuedImports.push(queuedImport);
}

View File

@ -7,10 +7,6 @@ import {
Function
} from "./program";
import {
sb
} from "./util/sb";
import {
NativeType,
ExpressionRef,

File diff suppressed because one or more lines are too long

View File

@ -1,23 +1,26 @@
//////////////////////////// Internal path utility /////////////////////////////
import {
CharCode
} from "./charcode";
const separator = CharCode.SLASH;
/** Normalizes the specified path, removing interior placeholders. Expects a posix-formatted string / not Windows compatible. */
/**
* Normalizes the specified path, removing interior placeholders.
* Expects a posix-compatible relative path (not Windows compatible).
*/
export function normalize(path: string): string {
// expects a relative path
var pos = 0;
var len = path.length;
// trim leading './'
while (pos + 1 < len && path.charCodeAt(pos) == CharCode.DOT && path.charCodeAt(pos + 1) == separator)
while (pos + 1 < len &&
path.charCodeAt(pos) == CharCode.DOT &&
path.charCodeAt(pos + 1) == separator
) {
pos += 2;
// trim extension if requested
// if (trimExtension && len > pos + 3 && path.charCodeAt(len - 3) == CharCode.DOT && (path.charCodeAt(len - 2) == CharCode.t || path.charCodeAt(len - 2) == CharCode.a) && path.charCodeAt(len - 1) == CharCode.s)
// len = len - 3;
}
if (pos > 0 || len < path.length) {
path = path.substring(pos, len);
@ -30,13 +33,15 @@ export function normalize(path: string): string {
atEnd = false;
// we are only interested in '/.' sequences ...
if (path.charCodeAt(pos) == separator && path.charCodeAt(pos + 1) == CharCode.DOT) {
if (
path.charCodeAt(pos) == separator &&
path.charCodeAt(pos + 1) == CharCode.DOT
) {
// '/.' ( '/' | $ )
if (
(atEnd = pos + 2 == len)
||
pos + 2 < len && path.charCodeAt(pos + 2) == separator
atEnd = pos + 2 == len;
if (atEnd ||
pos + 2 < len &&
path.charCodeAt(pos + 2) == separator
) {
path = atEnd
? path.substring(0, pos)
@ -46,17 +51,20 @@ export function normalize(path: string): string {
}
// '/.' ( './' | '.' $ )
if (
(atEnd = pos + 3 == len) && path.charCodeAt(pos + 2) == CharCode.DOT
||
pos + 3 < len && path.charCodeAt(pos + 2) == CharCode.DOT && path.charCodeAt(pos + 3) == separator
atEnd = pos + 3 == len;
if (atEnd && path.charCodeAt(pos + 2) == CharCode.DOT ||
pos + 3 < len &&
path.charCodeAt(pos + 2) == CharCode.DOT &&
path.charCodeAt(pos + 3) == separator
) {
// find preceeding '/'
var ipos = pos;
while (--ipos >= 0) {
if (path.charCodeAt(ipos) == separator) {
if (pos - ipos != 3 || path.charCodeAt(ipos + 1) != CharCode.DOT || path.charCodeAt(ipos + 2) != CharCode.DOT) { // exclude '..' itself
if (pos - ipos != 3 ||
path.charCodeAt(ipos + 1) != CharCode.DOT ||
path.charCodeAt(ipos + 2) != CharCode.DOT
) { // exclude '..' itself
path = atEnd
? path.substring(0, ipos)
: path.substring(0, ipos) + path.substring(pos + 3);
@ -69,7 +77,10 @@ export function normalize(path: string): string {
// if there's no preceeding '/', trim start if non-empty
if (ipos < 0 && pos > 0) {
if (pos != 2 || path.charCodeAt(0) != CharCode.DOT || path.charCodeAt(1) != CharCode.DOT) { // exclude '..' itself
if (pos != 2 ||
path.charCodeAt(0) != CharCode.DOT ||
path.charCodeAt(1) != CharCode.DOT
) { // exclude '..' itself
path = path.substring(pos + 4);
len = path.length;
continue;
@ -82,11 +93,13 @@ export function normalize(path: string): string {
return len > 0 ? path : ".";
}
/** Resolves the specified path to a normalized path relative to the specified origin. */
export function resolve(normalizedPath: string, normalizedOrigin: string): string {
/** Resolves the specified path relative to the specified origin. */
export function resolve(normalizedPath: string, origin: string): string {
if (normalizedPath.startsWith("std/"))
return normalizedPath;
return normalize(dirname(normalizedOrigin) + String.fromCharCode(separator) + normalizedPath);
return normalize(
dirname(origin) + String.fromCharCode(separator) + normalizedPath
);
}
/** Obtains the directory portion of a normalized path. */

View File

@ -1,2 +0,0 @@
/** A shared string builder utilized to reduce overall array allocations. */
export const sb = new Array<string>();