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

4
dist/asc.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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>();

View File

@ -15,6 +15,4 @@ export function free_memory(ptr: usize): void {
_free(ptr);
}
export function reset_memory(): void {
throw new Error("not supported");
}
export { reset_memory } from "./none";

View File

@ -0,0 +1,11 @@
export function allocate_memory(size: usize): usize {
throw new Error("not supported");
}
export function free_memory(ptr: usize): void {
throw new Error("not supported");
}
export function reset_memory(): void {
throw new Error("not supported");
}

View File

@ -14,6 +14,4 @@ export function free_memory(ptr: usize): void {
free(ptr);
}
export function reset_memory(): void {
throw new Error("not supported");
}
export { reset_memory } from "./none";

View File

@ -486,3 +486,5 @@ export function free_memory(data: usize): void {
}
}
}
export { reset_memory } from "./none";