mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Support 'import * as' directives, see #27
This commit is contained in:
parent
f2eb64c0fd
commit
25b433dca9
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -602,7 +602,7 @@ export abstract class Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static createExportStatement(
|
static createExportStatement(
|
||||||
members: ExportMember[],
|
members: ExportMember[] | null,
|
||||||
path: StringLiteralExpression | null,
|
path: StringLiteralExpression | null,
|
||||||
flags: CommonFlags,
|
flags: CommonFlags,
|
||||||
range: Range
|
range: Range
|
||||||
@ -610,7 +610,7 @@ export abstract class Node {
|
|||||||
var stmt = new ExportStatement();
|
var stmt = new ExportStatement();
|
||||||
stmt.range = range;
|
stmt.range = range;
|
||||||
stmt.flags = flags;
|
stmt.flags = flags;
|
||||||
stmt.members = members; setParent(members, stmt);
|
stmt.members = members; if (members) setParent(members, stmt);
|
||||||
stmt.path = path;
|
stmt.path = path;
|
||||||
if (path) {
|
if (path) {
|
||||||
let normalizedPath = normalizePath(path.value);
|
let normalizedPath = normalizePath(path.value);
|
||||||
@ -1627,8 +1627,8 @@ export class ExportMember extends Node {
|
|||||||
export class ExportStatement extends Statement {
|
export class ExportStatement extends Statement {
|
||||||
kind = NodeKind.EXPORT;
|
kind = NodeKind.EXPORT;
|
||||||
|
|
||||||
/** Array of members. */
|
/** Array of members if a set of named exports, or `null` if a filespace export. */
|
||||||
members: ExportMember[];
|
members: ExportMember[] | null;
|
||||||
/** Path being exported from, if applicable. */
|
/** Path being exported from, if applicable. */
|
||||||
path: StringLiteralExpression | null;
|
path: StringLiteralExpression | null;
|
||||||
/** Normalized path, if `path` is set. */
|
/** Normalized path, if `path` is set. */
|
||||||
|
@ -1097,8 +1097,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
compileExportStatement(statement: ExportStatement): void {
|
compileExportStatement(statement: ExportStatement): void {
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
var exports = this.program.fileLevelExports;
|
var fileLevelExports = this.program.fileLevelExports;
|
||||||
var members = statement.members;
|
var members = statement.members;
|
||||||
|
if (!members) return; // filespace
|
||||||
for (let i = 0, k = members.length; i < k; ++i) {
|
for (let i = 0, k = members.length; i < k; ++i) {
|
||||||
let member = members[i];
|
let member = members[i];
|
||||||
let internalExportName = (
|
let internalExportName = (
|
||||||
@ -1106,7 +1107,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
PATH_DELIMITER +
|
PATH_DELIMITER +
|
||||||
member.externalName.text
|
member.externalName.text
|
||||||
);
|
);
|
||||||
let element = exports.get(internalExportName);
|
let element = fileLevelExports.get(internalExportName);
|
||||||
if (!element) continue; // reported in Program#initialize
|
if (!element) continue; // reported in Program#initialize
|
||||||
switch (element.kind) {
|
switch (element.kind) {
|
||||||
case ElementKind.CLASS_PROTOTYPE: {
|
case ElementKind.CLASS_PROTOTYPE: {
|
||||||
|
@ -1915,6 +1915,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// at 'export': '{' ExportMember (',' ExportMember)* }' ('from' StringLiteral)? ';'?
|
// at 'export': '{' ExportMember (',' ExportMember)* }' ('from' StringLiteral)? ';'?
|
||||||
|
|
||||||
|
var path: StringLiteralExpression | null = null;
|
||||||
if (tn.skip(Token.OPENBRACE)) {
|
if (tn.skip(Token.OPENBRACE)) {
|
||||||
let members = new Array<ExportMember>();
|
let members = new Array<ExportMember>();
|
||||||
while (!tn.skip(Token.CLOSEBRACE)) {
|
while (!tn.skip(Token.CLOSEBRACE)) {
|
||||||
@ -1933,7 +1934,6 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let path: StringLiteralExpression | null = null;
|
|
||||||
if (tn.skip(Token.FROM)) {
|
if (tn.skip(Token.FROM)) {
|
||||||
if (tn.skip(Token.STRINGLITERAL)) {
|
if (tn.skip(Token.STRINGLITERAL)) {
|
||||||
path = Node.createStringLiteralExpression(tn.readString(), tn.range());
|
path = Node.createStringLiteralExpression(tn.readString(), tn.range());
|
||||||
@ -1953,6 +1953,30 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
tn.skip(Token.SEMICOLON);
|
tn.skip(Token.SEMICOLON);
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if (tn.skip(Token.ASTERISK)) {
|
||||||
|
if (tn.skip(Token.FROM)) {
|
||||||
|
if (tn.skip(Token.STRINGLITERAL)) {
|
||||||
|
path = Node.createStringLiteralExpression(tn.readString(), tn.range());
|
||||||
|
let ret = Node.createExportStatement(null, path, flags, tn.range(startPos, tn.pos));
|
||||||
|
let internalPath = ret.internalPath;
|
||||||
|
if (internalPath !== null && !this.seenlog.has(internalPath)) {
|
||||||
|
this.backlog.push(internalPath);
|
||||||
|
this.seenlog.add(internalPath);
|
||||||
|
}
|
||||||
|
tn.skip(Token.SEMICOLON);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.String_literal_expected,
|
||||||
|
tn.range()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode._0_expected,
|
||||||
|
tn.range(), "from"
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode._0_expected,
|
DiagnosticCode._0_expected,
|
||||||
@ -2805,8 +2829,8 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
return Node.createFalseExpression(tn.range());
|
return Node.createFalseExpression(tn.range());
|
||||||
}
|
}
|
||||||
|
|
||||||
var p = determinePrecedenceStart(token);
|
var precedence = determinePrecedenceStart(token);
|
||||||
if (p != Precedence.INVALID) {
|
if (precedence != Precedence.INVALID) {
|
||||||
let operand: Expression | null;
|
let operand: Expression | null;
|
||||||
|
|
||||||
// TODO: SpreadExpression, YieldExpression (currently become unsupported UnaryPrefixExpressions)
|
// TODO: SpreadExpression, YieldExpression (currently become unsupported UnaryPrefixExpressions)
|
||||||
@ -2830,7 +2854,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
operand = this.parseExpression(tn, p);
|
operand = this.parseExpression(tn, precedence);
|
||||||
if (!operand) return null;
|
if (!operand) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3328,7 +3352,7 @@ export const enum Precedence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Determines the precedence of a starting token. */
|
/** Determines the precedence of a starting token. */
|
||||||
function determinePrecedenceStart(kind: Token): i32 {
|
function determinePrecedenceStart(kind: Token): Precedence {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Token.DOT_DOT_DOT: return Precedence.SPREAD;
|
case Token.DOT_DOT_DOT: return Precedence.SPREAD;
|
||||||
case Token.YIELD: return Precedence.YIELD;
|
case Token.YIELD: return Precedence.YIELD;
|
||||||
@ -3347,7 +3371,7 @@ function determinePrecedenceStart(kind: Token): i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Determines the precende of a non-starting token. */
|
/** Determines the precende of a non-starting token. */
|
||||||
function determinePrecedence(kind: Token): i32 {
|
function determinePrecedence(kind: Token): Precedence {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case Token.COMMA: return Precedence.COMMA;
|
case Token.COMMA: return Precedence.COMMA;
|
||||||
case Token.EQUALS:
|
case Token.EQUALS:
|
||||||
|
133
src/program.ts
133
src/program.ts
@ -120,6 +120,8 @@ export const INNER_DELIMITER = "~";
|
|||||||
export const LIBRARY_SUBST = "~lib";
|
export const LIBRARY_SUBST = "~lib";
|
||||||
/** Library directory prefix. */
|
/** Library directory prefix. */
|
||||||
export const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;
|
export const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;
|
||||||
|
/** Prefix used to indicate a filespace element. */
|
||||||
|
export const FILESPACE_PREFIX = "file:";
|
||||||
|
|
||||||
/** Represents a yet unresolved export. */
|
/** Represents a yet unresolved export. */
|
||||||
class QueuedExport {
|
class QueuedExport {
|
||||||
@ -133,7 +135,7 @@ class QueuedImport {
|
|||||||
internalName: string;
|
internalName: string;
|
||||||
referencedName: string;
|
referencedName: string;
|
||||||
referencedNameAlt: string;
|
referencedNameAlt: string;
|
||||||
declaration: ImportDeclaration;
|
declaration: ImportDeclaration | null; // not set if a filespace
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents a type alias. */
|
/** Represents a type alias. */
|
||||||
@ -338,6 +340,8 @@ export class Program extends DiagnosticEmitter {
|
|||||||
resolvedThisExpression: Expression | null = null;
|
resolvedThisExpression: Expression | null = null;
|
||||||
/** Element expression of the previously resolved element access. */
|
/** Element expression of the previously resolved element access. */
|
||||||
resolvedElementExpression : Expression | null = null;
|
resolvedElementExpression : Expression | null = null;
|
||||||
|
/** Currently processing filespace. */
|
||||||
|
currentFilespace: Filespace;
|
||||||
|
|
||||||
/** Constructs a new program, optionally inheriting parser diagnostics. */
|
/** Constructs a new program, optionally inheriting parser diagnostics. */
|
||||||
constructor(diagnostics: DiagnosticMessage[] | null = null) {
|
constructor(diagnostics: DiagnosticMessage[] | null = null) {
|
||||||
@ -357,11 +361,12 @@ export class Program extends DiagnosticEmitter {
|
|||||||
|
|
||||||
/** Looks up the source for the specified possibly ambiguous path. */
|
/** Looks up the source for the specified possibly ambiguous path. */
|
||||||
lookupSourceByPath(normalizedPathWithoutExtension: string): Source | null {
|
lookupSourceByPath(normalizedPathWithoutExtension: string): Source | null {
|
||||||
|
var tmp: string;
|
||||||
return (
|
return (
|
||||||
this.getSource(normalizedPathWithoutExtension + ".ts") ||
|
this.getSource(normalizedPathWithoutExtension + ".ts") ||
|
||||||
this.getSource(normalizedPathWithoutExtension + "/index.ts") ||
|
this.getSource(normalizedPathWithoutExtension + "/index.ts") ||
|
||||||
this.getSource(LIBRARY_PREFIX + normalizedPathWithoutExtension + ".ts") ||
|
this.getSource((tmp = LIBRARY_PREFIX + normalizedPathWithoutExtension) + ".ts") ||
|
||||||
this.getSource(LIBRARY_PREFIX + normalizedPathWithoutExtension + "/index.ts")
|
this.getSource( tmp + "/index.ts")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,6 +400,13 @@ export class Program extends DiagnosticEmitter {
|
|||||||
// build initial lookup maps of internal names to declarations
|
// build initial lookup maps of internal names to declarations
|
||||||
for (let i = 0, k = this.sources.length; i < k; ++i) {
|
for (let i = 0, k = this.sources.length; i < k; ++i) {
|
||||||
let source = this.sources[i];
|
let source = this.sources[i];
|
||||||
|
|
||||||
|
// create one filespace per source
|
||||||
|
let filespace = new Filespace(this, source);
|
||||||
|
this.elementsLookup.set(filespace.internalName, filespace);
|
||||||
|
this.currentFilespace = filespace;
|
||||||
|
|
||||||
|
// process this source's statements
|
||||||
let statements = source.statements;
|
let statements = source.statements;
|
||||||
for (let j = 0, l = statements.length; j < l; ++j) {
|
for (let j = 0, l = statements.length; j < l; ++j) {
|
||||||
let statement = statements[j];
|
let statement = statements[j];
|
||||||
@ -442,6 +454,8 @@ export class Program extends DiagnosticEmitter {
|
|||||||
// queued imports should be resolvable now through traversing exports and queued exports
|
// queued imports should be resolvable now through traversing exports and queued exports
|
||||||
for (let i = 0; i < queuedImports.length;) {
|
for (let i = 0; i < queuedImports.length;) {
|
||||||
let queuedImport = queuedImports[i];
|
let queuedImport = queuedImports[i];
|
||||||
|
let declaration = queuedImport.declaration;
|
||||||
|
if (declaration) { // named
|
||||||
let element = this.tryResolveImport(queuedImport.referencedName, queuedExports);
|
let element = this.tryResolveImport(queuedImport.referencedName, queuedExports);
|
||||||
if (element) {
|
if (element) {
|
||||||
this.elementsLookup.set(queuedImport.internalName, element);
|
this.elementsLookup.set(queuedImport.internalName, element);
|
||||||
@ -453,13 +467,28 @@ export class Program extends DiagnosticEmitter {
|
|||||||
} else {
|
} else {
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode.Module_0_has_no_exported_member_1,
|
DiagnosticCode.Module_0_has_no_exported_member_1,
|
||||||
queuedImport.declaration.range,
|
declaration.range,
|
||||||
(<ImportStatement>queuedImport.declaration.parent).path.value,
|
(<ImportStatement>declaration.parent).path.value,
|
||||||
queuedImport.declaration.externalName.text
|
declaration.externalName.text
|
||||||
);
|
);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else { // filespace
|
||||||
|
let element = this.elementsLookup.get(queuedImport.referencedName);
|
||||||
|
if (element) {
|
||||||
|
this.elementsLookup.set(queuedImport.internalName, element);
|
||||||
|
queuedImports.splice(i, 1);
|
||||||
|
} else {
|
||||||
|
if (element = this.elementsLookup.get(queuedImport.referencedNameAlt)) {
|
||||||
|
this.elementsLookup.set(queuedImport.internalName, element);
|
||||||
|
queuedImports.splice(i, 1);
|
||||||
|
} else {
|
||||||
|
assert(false); // already reported by the parser not finding the file
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// queued exports should be resolvable now that imports are finalized
|
// queued exports should be resolvable now that imports are finalized
|
||||||
@ -732,6 +761,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fileLevelExports.set(internalName, prototype);
|
this.fileLevelExports.set(internalName, prototype);
|
||||||
|
this.currentFilespace.members.set(simpleName, prototype);
|
||||||
if (prototype.is(CommonFlags.EXPORT) && declaration.range.source.isEntry) {
|
if (prototype.is(CommonFlags.EXPORT) && declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1165,6 +1195,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fileLevelExports.set(internalName, element);
|
this.fileLevelExports.set(internalName, element);
|
||||||
|
this.currentFilespace.members.set(simpleName, element);
|
||||||
if (declaration.range.source.isEntry) {
|
if (declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1215,26 +1246,45 @@ export class Program extends DiagnosticEmitter {
|
|||||||
queuedExports: Map<string,QueuedExport>
|
queuedExports: Map<string,QueuedExport>
|
||||||
): void {
|
): void {
|
||||||
var members = statement.members;
|
var members = statement.members;
|
||||||
|
if (members) { // named
|
||||||
for (let i = 0, k = members.length; i < k; ++i) {
|
for (let i = 0, k = members.length; i < k; ++i) {
|
||||||
this.initializeExport(members[i], statement.internalPath, queuedExports);
|
this.initializeExport(members[i], statement.internalPath, queuedExports);
|
||||||
}
|
}
|
||||||
|
} else { // TODO: filespace
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
statement.range
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setExportAndCheckLibrary(
|
private setExportAndCheckLibrary(
|
||||||
name: string,
|
internalName: string,
|
||||||
element: Element,
|
element: Element,
|
||||||
identifier: IdentifierExpression
|
identifier: IdentifierExpression
|
||||||
): void {
|
): void {
|
||||||
this.fileLevelExports.set(name, element);
|
// add to file-level exports
|
||||||
if (identifier.range.source.isLibrary) { // add global alias
|
this.fileLevelExports.set(internalName, element);
|
||||||
if (this.elementsLookup.has(identifier.text)) {
|
|
||||||
|
// add to filespace
|
||||||
|
var internalPath = identifier.range.source.internalPath;
|
||||||
|
var prefix = FILESPACE_PREFIX + internalPath;
|
||||||
|
var filespace = this.elementsLookup.get(prefix);
|
||||||
|
if (!filespace) filespace = assert(this.elementsLookup.get(prefix + PATH_DELIMITER + "index"));
|
||||||
|
assert(filespace.kind == ElementKind.FILESPACE);
|
||||||
|
var simpleName = identifier.text;
|
||||||
|
(<Filespace>filespace).members.set(simpleName, element);
|
||||||
|
|
||||||
|
// add global alias if from a library file
|
||||||
|
if (identifier.range.source.isLibrary) {
|
||||||
|
if (this.elementsLookup.has(simpleName)) {
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0,
|
DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0,
|
||||||
identifier.range, identifier.text
|
identifier.range, simpleName
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
element.internalName = identifier.text;
|
element.internalName = simpleName;
|
||||||
this.elementsLookup.set(identifier.text, element);
|
this.elementsLookup.set(simpleName, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1401,6 +1451,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fileLevelExports.set(internalName, prototype);
|
this.fileLevelExports.set(internalName, prototype);
|
||||||
|
this.currentFilespace.members.set(simpleName, prototype);
|
||||||
if (declaration.range.source.isEntry) {
|
if (declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1446,10 +1497,22 @@ export class Program extends DiagnosticEmitter {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.error( // TODO
|
|
||||||
DiagnosticCode.Operation_not_supported,
|
// resolve right away if the exact filespace exists
|
||||||
statement.range
|
let filespace = this.elementsLookup.get(statement.internalPath);
|
||||||
);
|
if (filespace) {
|
||||||
|
this.elementsLookup.set(internalName, filespace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise queue it
|
||||||
|
let queuedImport = new QueuedImport();
|
||||||
|
queuedImport.internalName = internalName;
|
||||||
|
let prefix = FILESPACE_PREFIX + statement.internalPath;
|
||||||
|
queuedImport.referencedName = prefix;
|
||||||
|
queuedImport.referencedNameAlt = prefix + PATH_DELIMITER + "index";
|
||||||
|
queuedImport.declaration = null;
|
||||||
|
queuedImports.push(queuedImport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1511,9 +1574,10 @@ export class Program extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var decorators = declaration.decorators;
|
var decorators = declaration.decorators;
|
||||||
|
var simpleName = declaration.name.text;
|
||||||
var prototype = new InterfacePrototype(
|
var prototype = new InterfacePrototype(
|
||||||
this,
|
this,
|
||||||
declaration.name.text,
|
simpleName,
|
||||||
internalName,
|
internalName,
|
||||||
declaration,
|
declaration,
|
||||||
decorators
|
decorators
|
||||||
@ -1548,6 +1612,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fileLevelExports.set(internalName, prototype);
|
this.fileLevelExports.set(internalName, prototype);
|
||||||
|
this.currentFilespace.members.set(simpleName, prototype);
|
||||||
if (declaration.range.source.isEntry) {
|
if (declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1632,6 +1697,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
} else {
|
} else {
|
||||||
this.fileLevelExports.set(internalName, namespace);
|
this.fileLevelExports.set(internalName, namespace);
|
||||||
}
|
}
|
||||||
|
this.currentFilespace.members.set(simpleName, namespace);
|
||||||
if (declaration.range.source.isEntry) {
|
if (declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1759,6 +1825,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
} else {
|
} else {
|
||||||
this.fileLevelExports.set(internalName, global);
|
this.fileLevelExports.set(internalName, global);
|
||||||
}
|
}
|
||||||
|
this.currentFilespace.members.set(simpleName, global);
|
||||||
if (declaration.range.source.isEntry) {
|
if (declaration.range.source.isEntry) {
|
||||||
if (this.moduleLevelExports.has(internalName)) {
|
if (this.moduleLevelExports.has(internalName)) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -2144,12 +2211,14 @@ export class Program extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
default: { // enums or other namespace-like elements
|
default: { // enums or other namespace-like elements
|
||||||
let members = target.members;
|
let members = target.members;
|
||||||
let member: Element | null;
|
if (members) {
|
||||||
if (members && (member = members.get(propertyName))) {
|
let member = members.get(propertyName);
|
||||||
|
if (member) {
|
||||||
this.resolvedThisExpression = targetExpression;
|
this.resolvedThisExpression = targetExpression;
|
||||||
this.resolvedElementExpression = null;
|
this.resolvedElementExpression = null;
|
||||||
return member; // static ENUMVALUE, static GLOBAL, static FUNCTION_PROTOTYPE...
|
return member; // static ENUMVALUE, static GLOBAL, static FUNCTION_PROTOTYPE...
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2373,7 +2442,9 @@ export enum ElementKind {
|
|||||||
/** A {@link Property}. */
|
/** A {@link Property}. */
|
||||||
PROPERTY,
|
PROPERTY,
|
||||||
/** A {@link Namespace}. */
|
/** A {@link Namespace}. */
|
||||||
NAMESPACE
|
NAMESPACE,
|
||||||
|
/** A {@link Filespace}. */
|
||||||
|
FILESPACE,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Indicates traits of a {@link Node} or {@link Element}. */
|
/** Indicates traits of a {@link Node} or {@link Element}. */
|
||||||
@ -2515,7 +2586,25 @@ export abstract class Element {
|
|||||||
hasDecorator(flag: DecoratorFlags): bool { return (this.decoratorFlags & flag) == flag; }
|
hasDecorator(flag: DecoratorFlags): bool { return (this.decoratorFlags & flag) == flag; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A namespace. */
|
/** A filespace representing the implicit top-level namespace of a source. */
|
||||||
|
export class Filespace extends Element {
|
||||||
|
|
||||||
|
kind = ElementKind.FILESPACE;
|
||||||
|
|
||||||
|
/** File members (externally visible only). */
|
||||||
|
members: Map<string,Element>; // more specific
|
||||||
|
|
||||||
|
/** Constructs a new filespace. */
|
||||||
|
constructor(
|
||||||
|
program: Program,
|
||||||
|
source: Source
|
||||||
|
) {
|
||||||
|
super(program, source.internalPath, FILESPACE_PREFIX + source.internalPath);
|
||||||
|
this.members = new Map();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A namespace that differs from a filespace in being user-declared with a name. */
|
||||||
export class Namespace extends Element {
|
export class Namespace extends Element {
|
||||||
|
|
||||||
// All elements have namespace semantics. This is an explicitly declared one.
|
// All elements have namespace semantics. This is an explicitly declared one.
|
||||||
|
@ -45,5 +45,24 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(call $export/ns.two)
|
(call $export/ns.two)
|
||||||
|
(drop
|
||||||
|
(i32.add
|
||||||
|
(i32.add
|
||||||
|
(call $export/add
|
||||||
|
(i32.const 1)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(call $export/sub
|
||||||
|
(i32.const 2)
|
||||||
|
(i32.const 3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call $export/mul
|
||||||
|
(i32.const 3)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call $export/ns.two)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
/* tslint:disable:no-duplicate-imports */
|
||||||
|
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
sub as sub,
|
sub as sub,
|
||||||
@ -11,3 +13,11 @@ import {
|
|||||||
add(a, b) + sub(b, c) + mul(c, a);
|
add(a, b) + sub(b, c) + mul(c, a);
|
||||||
|
|
||||||
renamed_ns.two();
|
renamed_ns.two();
|
||||||
|
|
||||||
|
import * as other from "./export";
|
||||||
|
|
||||||
|
other.add(other.a, other.b) +
|
||||||
|
other.sub(other.b, other.renamed_c) +
|
||||||
|
other.renamed_mul(other.renamed_c, other.a);
|
||||||
|
|
||||||
|
other.ns.two();
|
||||||
|
@ -55,5 +55,24 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(call $export/ns.two)
|
(call $export/ns.two)
|
||||||
|
(drop
|
||||||
|
(i32.add
|
||||||
|
(i32.add
|
||||||
|
(call $export/add
|
||||||
|
(i32.const 1)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(call $export/sub
|
||||||
|
(i32.const 2)
|
||||||
|
(i32.const 3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call $export/mul
|
||||||
|
(i32.const 3)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(call $export/ns.two)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user