mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Cleanup; Fix an issue with 'let' declarations reusing a local
This commit is contained in:
parent
b1c6ccab2a
commit
d31e484b15
@ -173,7 +173,7 @@ exports.main = function main(argv, options, callback) {
|
||||
|
||||
stats.parseCount++;
|
||||
stats.parseTime += measure(() => {
|
||||
parser = assemblyscript.parseFile(sourceText, sourcePath, parser, true);
|
||||
parser = assemblyscript.parseFile(sourceText, sourcePath, true, parser);
|
||||
});
|
||||
|
||||
while ((sourcePath = parser.nextFile()) != null) {
|
||||
@ -226,7 +226,7 @@ exports.main = function main(argv, options, callback) {
|
||||
}
|
||||
stats.parseCount++;
|
||||
stats.parseTime += measure(() => {
|
||||
assemblyscript.parseFile(sourceText, sourcePath, parser);
|
||||
assemblyscript.parseFile(sourceText, sourcePath, false, parser);
|
||||
});
|
||||
}
|
||||
if (checkDiagnostics(parser, stderr))
|
||||
@ -244,6 +244,7 @@ exports.main = function main(argv, options, callback) {
|
||||
parser = assemblyscript.parseFile(
|
||||
exports.libraryFiles[libPath],
|
||||
libPath + ".ts",
|
||||
false,
|
||||
parser
|
||||
);
|
||||
});
|
||||
@ -263,6 +264,7 @@ exports.main = function main(argv, options, callback) {
|
||||
parser = assemblyscript.parseFile(
|
||||
libText,
|
||||
exports.libraryPrefix + libPath,
|
||||
false,
|
||||
parser
|
||||
);
|
||||
});
|
||||
|
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
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
863
src/ast.ts
863
src/ast.ts
File diff suppressed because it is too large
Load Diff
@ -12,9 +12,7 @@ import {
|
||||
|
||||
import {
|
||||
Node,
|
||||
Expression,
|
||||
BinaryExpression,
|
||||
SourceKind
|
||||
Expression
|
||||
} from "./ast";
|
||||
|
||||
import {
|
||||
@ -24,7 +22,6 @@ import {
|
||||
} from "./types";
|
||||
|
||||
import {
|
||||
Module,
|
||||
UnaryOp,
|
||||
BinaryOp,
|
||||
HostOp,
|
||||
@ -35,11 +32,8 @@ import {
|
||||
} from "./module";
|
||||
|
||||
import {
|
||||
Program,
|
||||
Global,
|
||||
Function,
|
||||
FunctionPrototype,
|
||||
Parameter,
|
||||
Local,
|
||||
ElementFlags,
|
||||
Class,
|
||||
@ -48,21 +42,21 @@ import {
|
||||
|
||||
/** Compiles a get of a built-in global. */
|
||||
export function compileGetConstant(compiler: Compiler, global: Global, reportNode: Node): ExpressionRef {
|
||||
switch (global.internalName) { // switching on strings should become a compiler optimization eventually
|
||||
switch (global.internalName) {
|
||||
|
||||
case "NaN":
|
||||
case "NaN": // context-sensitive
|
||||
if (compiler.currentType == Type.f32)
|
||||
return compiler.module.createF32(NaN);
|
||||
compiler.currentType = Type.f64;
|
||||
return compiler.module.createF64(NaN);
|
||||
|
||||
case "Infinity":
|
||||
case "Infinity": // context-sensitive
|
||||
if (compiler.currentType == Type.f32)
|
||||
return compiler.module.createF32(Infinity);
|
||||
compiler.currentType = Type.f64;
|
||||
return compiler.module.createF64(Infinity);
|
||||
|
||||
case "HEAP_BASE": // constant, but never inlined
|
||||
case "HEAP_BASE": // never inlined for linking purposes
|
||||
compiler.currentType = compiler.options.usizeType;
|
||||
return compiler.module.createGetGlobal("HEAP_BASE", compiler.options.nativeSizeType);
|
||||
}
|
||||
@ -83,9 +77,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty
|
||||
tempLocal1: Local;
|
||||
|
||||
var type: Type,
|
||||
ftype: FunctionTypeRef;
|
||||
|
||||
var offset: i32;
|
||||
offset: i32;
|
||||
|
||||
// NOTE that some implementations below make use of the select expression where straight-forward.
|
||||
// whether worth or not should probably be tested once it's known if/how embedders handle it.
|
||||
|
@ -648,7 +648,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// check module export
|
||||
if (declaration.range.source.isEntry && declaration.isTopLevelExport)
|
||||
this.module.addFunctionExport(instance.internalName, declaration.name.name);
|
||||
this.module.addFunctionExport(instance.internalName, declaration.name.text);
|
||||
|
||||
instance.finalize(this.module, ref);
|
||||
return true;
|
||||
@ -741,7 +741,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var members = statement.members;
|
||||
for (var i = 0, k = members.length; i < k; ++i) {
|
||||
var member = members[i];
|
||||
var internalExportName = statement.range.source.internalPath + PATH_DELIMITER + member.externalIdentifier.name;
|
||||
var internalExportName = statement.range.source.internalPath + PATH_DELIMITER + member.externalName.text;
|
||||
var element = this.program.exports.get(internalExportName);
|
||||
if (!element) // reported in Program#initialize
|
||||
continue;
|
||||
@ -762,7 +762,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (functionInstance) {
|
||||
var functionDeclaration = functionInstance.prototype.declaration;
|
||||
if (functionDeclaration && functionDeclaration.needsExplicitExport(member))
|
||||
this.module.addFunctionExport(functionInstance.internalName, member.externalIdentifier.name);
|
||||
this.module.addFunctionExport(functionInstance.internalName, member.externalName.text);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -772,7 +772,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var globalDeclaration = (<Global>element).declaration;
|
||||
if (globalDeclaration && globalDeclaration.needsExplicitExport(member)) {
|
||||
if ((<Global>element).is(ElementFlags.INLINED))
|
||||
this.module.addGlobalExport(element.internalName, member.externalIdentifier.name);
|
||||
this.module.addGlobalExport(element.internalName, member.externalName.text);
|
||||
else
|
||||
this.warning(DiagnosticCode.Cannot_export_a_mutable_global, member.range);
|
||||
}
|
||||
@ -1195,7 +1195,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var initializers = new Array<ExpressionRef>();
|
||||
for (i = 0, k = declarations.length; i < k; ++i) {
|
||||
var declaration = declarations[i];
|
||||
var name = declaration.name.name;
|
||||
var name = declaration.name.text;
|
||||
var type: Type | null = null;
|
||||
var init: ExpressionRef = 0;
|
||||
if (declaration.type) {
|
||||
|
@ -309,7 +309,7 @@ export function serializeSource(source: Source, sb: string[]): void {
|
||||
// types
|
||||
|
||||
export function serializeTypeNode(node: TypeNode, sb: string[]): void {
|
||||
serializeIdentifierExpression(<IdentifierExpression>node.identifier, sb);
|
||||
serializeIdentifierExpression(<IdentifierExpression>node.name, sb);
|
||||
if (node.typeArguments.length) {
|
||||
sb.push("<");
|
||||
for (var i = 0, k = node.typeArguments.length; i < k; ++i) {
|
||||
@ -324,7 +324,7 @@ export function serializeTypeNode(node: TypeNode, sb: string[]): void {
|
||||
}
|
||||
|
||||
export function serializeTypeParameter(node: TypeParameter, sb: string[]): void {
|
||||
serializeIdentifierExpression(node.identifier, sb);
|
||||
serializeIdentifierExpression(node.name, sb);
|
||||
if (node.extendsType) {
|
||||
sb.push(" extends ");
|
||||
serializeTypeNode(node.extendsType, sb);
|
||||
@ -338,7 +338,7 @@ export function serializeExpression(node: Expression, sb: string[]): void {
|
||||
}
|
||||
|
||||
export function serializeIdentifierExpression(node: IdentifierExpression, sb: string[]): void {
|
||||
sb.push(node.name);
|
||||
sb.push(node.text);
|
||||
}
|
||||
|
||||
export function serializeArrayLiteralExpression(node: ArrayLiteralExpression, sb: string[]): void {
|
||||
@ -705,7 +705,7 @@ export function serializeClassDeclaration(node: ClassDeclaration, sb: string[]):
|
||||
sb.push(" ");
|
||||
}
|
||||
sb.push("class ");
|
||||
sb.push(node.name.name);
|
||||
sb.push(node.name.text);
|
||||
if (node.typeParameters.length) {
|
||||
sb.push("<");
|
||||
for (i = 0, k = node.typeParameters.length; i < k; ++i) {
|
||||
@ -779,16 +779,16 @@ export function serializeEnumValueDeclaration(node: EnumValueDeclaration, sb: st
|
||||
|
||||
export function serializeExportImportStatement(node: ExportImportStatement, sb: string[]): void {
|
||||
sb.push("export import ");
|
||||
serializeIdentifierExpression(node.externalIdentifier, sb);
|
||||
serializeIdentifierExpression(node.externalName, sb);
|
||||
sb.push(" = ");
|
||||
serializeIdentifierExpression(node.identifier, sb);
|
||||
serializeIdentifierExpression(node.name, sb);
|
||||
}
|
||||
|
||||
export function serializeExportMember(node: ExportMember, sb: string[]): void {
|
||||
serializeIdentifierExpression(node.identifier, sb);
|
||||
if (node.externalIdentifier.name != node.identifier.name) {
|
||||
serializeIdentifierExpression(node.name, sb);
|
||||
if (node.externalName.text != node.name.text) {
|
||||
sb.push(" as ");
|
||||
serializeIdentifierExpression(node.externalIdentifier, sb);
|
||||
serializeIdentifierExpression(node.externalName, sb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -922,8 +922,8 @@ export function serializeIfStatement(node: IfStatement, sb: string[]): void {
|
||||
}
|
||||
|
||||
export function serializeImportDeclaration(node: ImportDeclaration, sb: string[]): void {
|
||||
serializeIdentifierExpression(node.externalIdentifier, sb);
|
||||
if (node.externalIdentifier != node.name) {
|
||||
serializeIdentifierExpression(node.externalName, sb);
|
||||
if (node.externalName.text != node.name.text) {
|
||||
sb.push(" as ");
|
||||
serializeIdentifierExpression(node.name, sb);
|
||||
}
|
||||
|
63
src/index.ts
63
src/index.ts
@ -1,30 +1,4 @@
|
||||
/*
|
||||
|
||||
Exports a C-like API to the embedder.
|
||||
|
||||
[obtain entrySource, entryPath]
|
||||
parseFile(entrySource, entryPath) -> parser
|
||||
while nextPath = nextFile(parser)
|
||||
[obtain nextSource]
|
||||
parseFile(nextSource, nextPath)
|
||||
|
||||
Checking for errors:
|
||||
|
||||
while diagnostic = nextDiagnostic(parser)
|
||||
[print] formatDiagnostic(diagnostic, useColors?, showContext?)
|
||||
if (isError(diagnostic))
|
||||
[abort parsing afterwards]
|
||||
|
||||
compile(parser) -> module
|
||||
|
||||
[check diagnostics again]
|
||||
[output module]
|
||||
|
||||
*/
|
||||
|
||||
import {
|
||||
Module
|
||||
} from "./module";
|
||||
//////////////////////// Low-level C-Like Compiler API /////////////////////////
|
||||
|
||||
import {
|
||||
Compiler,
|
||||
@ -32,28 +6,28 @@ import {
|
||||
Target
|
||||
} from "./compiler";
|
||||
|
||||
import {
|
||||
Decompiler
|
||||
} from "./decompiler";
|
||||
|
||||
import {
|
||||
DiagnosticMessage,
|
||||
DiagnosticCategory,
|
||||
formatDiagnosticMessage
|
||||
} from "./diagnostics";
|
||||
|
||||
import {
|
||||
Module
|
||||
} from "./module";
|
||||
|
||||
import {
|
||||
Parser
|
||||
} from "./parser";
|
||||
|
||||
import {
|
||||
Program
|
||||
} from "./program";
|
||||
|
||||
import {
|
||||
Decompiler
|
||||
} from "./decompiler";
|
||||
|
||||
export { LIBRARY_PREFIX } from "./program";
|
||||
|
||||
/** Parses a single source file. If `parser` has been omitted a new one is created. */
|
||||
export function parseFile(text: string, path: string, parser: Parser | null = null, isEntry: bool = false): Parser {
|
||||
/** Parses a source file. If `parser` has been omitted a new one is created. */
|
||||
export function parseFile(text: string, path: string, isEntry: bool = false,
|
||||
parser: Parser | null = null
|
||||
): Parser {
|
||||
if (!parser) {
|
||||
parser = new Parser();
|
||||
isEntry = true;
|
||||
@ -62,12 +36,12 @@ export function parseFile(text: string, path: string, parser: Parser | null = nu
|
||||
return parser;
|
||||
}
|
||||
|
||||
/** Obtains the path to the next file required by the parser. Returns `null` once complete. */
|
||||
/** Obtains the next required file's path. Returns `null` once complete. */
|
||||
export function nextFile(parser: Parser): string | null {
|
||||
return parser.nextFile();
|
||||
}
|
||||
|
||||
/** Obtains the next diagnostic message. Returns `null` once there are no more messages. */
|
||||
/** Obtains the next diagnostic message. Returns `null` once complete. */
|
||||
export function nextDiagnostic(parser: Parser): DiagnosticMessage | null {
|
||||
var program = parser.program;
|
||||
return program.diagnosticsOffset < program.diagnostics.length
|
||||
@ -76,9 +50,7 @@ export function nextDiagnostic(parser: Parser): DiagnosticMessage | null {
|
||||
}
|
||||
|
||||
/** Formats a diagnostic message to a string. */
|
||||
export function formatDiagnostic(message: DiagnosticMessage, useColors: bool, showContext: bool): string {
|
||||
return formatDiagnosticMessage(message, useColors, showContext);
|
||||
}
|
||||
export { formatDiagnosticMessage as formatDiagnostic };
|
||||
|
||||
/** Tests whether a diagnostic is informatory. */
|
||||
export function isInfo(message: DiagnosticMessage): bool {
|
||||
@ -138,3 +110,6 @@ export function decompile(module: Module): string {
|
||||
decompiler.decompile(module);
|
||||
return decompiler.finish();
|
||||
}
|
||||
|
||||
/** Prefix indicating a library file. */
|
||||
export { LIBRARY_PREFIX } from "./program";
|
||||
|
128
src/program.ts
128
src/program.ts
@ -60,7 +60,6 @@ import {
|
||||
hasDecorator,
|
||||
hasModifier,
|
||||
mangleInternalName,
|
||||
getFirstDecorator,
|
||||
BinaryExpression
|
||||
} from "./ast";
|
||||
|
||||
@ -210,7 +209,7 @@ 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.externalIdentifier.name);
|
||||
this.error(DiagnosticCode.Module_0_has_no_exported_member_1, queuedImport.declaration.range, (<ImportStatement>queuedImport.declaration.parent).path.value, queuedImport.declaration.externalName.text);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
@ -221,20 +220,20 @@ export class Program extends DiagnosticEmitter {
|
||||
do {
|
||||
if (currentExport.isReExport) {
|
||||
if (element = this.exports.get(currentExport.referencedName)) {
|
||||
this.setExportAndCheckLibrary(exportName, element, currentExport.member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(exportName, element, currentExport.member.externalName);
|
||||
break;
|
||||
}
|
||||
currentExport = queuedExports.get(currentExport.referencedName);
|
||||
if (!currentExport)
|
||||
this.error(DiagnosticCode.Module_0_has_no_exported_member_1, queuedExport.member.externalIdentifier.range, (<StringLiteralExpression>(<ExportStatement>queuedExport.member.parent).path).value, queuedExport.member.externalIdentifier.name);
|
||||
this.error(DiagnosticCode.Module_0_has_no_exported_member_1, queuedExport.member.externalName.range, (<StringLiteralExpression>(<ExportStatement>queuedExport.member.parent).path).value, queuedExport.member.externalName.text);
|
||||
} else {
|
||||
if (
|
||||
(element = this.elements.get(currentExport.referencedName)) || // normal export
|
||||
(element = this.elements.get(currentExport.member.identifier.name)) // library re-export
|
||||
(element = this.elements.get(currentExport.member.name.text)) // library re-export
|
||||
)
|
||||
this.setExportAndCheckLibrary(exportName, element, currentExport.member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(exportName, element, currentExport.member.externalName);
|
||||
else
|
||||
this.error(DiagnosticCode.Cannot_find_name_0, queuedExport.member.range, queuedExport.member.identifier.name);
|
||||
this.error(DiagnosticCode.Cannot_find_name_0, queuedExport.member.range, queuedExport.member.name.text);
|
||||
break;
|
||||
}
|
||||
} while (currentExport);
|
||||
@ -246,7 +245,7 @@ export class Program extends DiagnosticEmitter {
|
||||
assert(derivedDeclaration != null);
|
||||
var derivedType = (<ClassDeclaration>derivedDeclaration).extendsType;
|
||||
assert(derivedType != null);
|
||||
var resolved = this.resolveIdentifier((<TypeNode>derivedType).identifier, null); // reports
|
||||
var resolved = this.resolveIdentifier((<TypeNode>derivedType).name, null); // reports
|
||||
if (resolved) {
|
||||
if (resolved.element.kind != ElementKind.CLASS_PROTOTYPE) {
|
||||
this.error(DiagnosticCode.A_class_may_only_extend_another_class, (<TypeNode>derivedType).range);
|
||||
@ -292,13 +291,13 @@ export class Program extends DiagnosticEmitter {
|
||||
)
|
||||
) {
|
||||
element.set(ElementFlags.GLOBAL);
|
||||
if (this.elements.has(declaration.name.name))
|
||||
if (this.elements.has(declaration.name.text))
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, element.internalName);
|
||||
else {
|
||||
this.elements.set(declaration.name.name, element);
|
||||
this.exports.set(declaration.name.name, element);
|
||||
this.elements.set(declaration.name.text, element);
|
||||
this.exports.set(declaration.name.text, element);
|
||||
if (isBuiltin)
|
||||
element.internalName = declaration.name.name;
|
||||
element.internalName = declaration.name.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,7 +308,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
var prototype = new ClassPrototype(this, declaration.name.name, internalName, declaration);
|
||||
var prototype = new ClassPrototype(this, declaration.name.text, internalName, declaration);
|
||||
prototype.namespace = namespace;
|
||||
this.elements.set(internalName, prototype);
|
||||
|
||||
@ -329,13 +328,13 @@ export class Program extends DiagnosticEmitter {
|
||||
// add as namespace member if applicable
|
||||
if (namespace) {
|
||||
if (namespace.members) {
|
||||
if (namespace.members.has(declaration.name.name)) {
|
||||
if (namespace.members.has(declaration.name.text)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
namespace.members = new Map();
|
||||
namespace.members.set(declaration.name.name, prototype);
|
||||
namespace.members.set(declaration.name.text, prototype);
|
||||
|
||||
// otherwise add to file-level exports if exported
|
||||
} else if (prototype.is(ElementFlags.EXPORTED)) {
|
||||
@ -370,7 +369,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// check and possibly register string type
|
||||
if (prototype.is(ElementFlags.GLOBAL) && declaration.name.name === "String" && !this.types.has("string")) {
|
||||
if (prototype.is(ElementFlags.GLOBAL) && declaration.name.text === "String" && !this.types.has("string")) {
|
||||
var instance = prototype.resolve(null);
|
||||
if (instance)
|
||||
this.types.set("string", instance.type);
|
||||
@ -378,7 +377,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
private initializeField(declaration: FieldDeclaration, classPrototype: ClassPrototype): void {
|
||||
var name = declaration.name.name;
|
||||
var name = declaration.name.text;
|
||||
var internalName = declaration.fileLevelInternalName;
|
||||
|
||||
// static fields become global variables
|
||||
@ -413,7 +412,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
private initializeMethod(declaration: MethodDeclaration, classPrototype: ClassPrototype): void {
|
||||
var name = declaration.name.name;
|
||||
var name = declaration.name.text;
|
||||
var internalName = declaration.fileLevelInternalName;
|
||||
var prototype: FunctionPrototype | null = null;
|
||||
|
||||
@ -511,7 +510,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
private initializeAccessor(declaration: MethodDeclaration, classPrototype: ClassPrototype, isGetter: bool): void {
|
||||
var propertyName = declaration.name.name;
|
||||
var propertyName = declaration.name.text;
|
||||
var internalPropertyName = declaration.fileLevelInternalName;
|
||||
|
||||
var propertyElement = this.elements.get(internalPropertyName);
|
||||
@ -568,7 +567,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
var enm = new Enum(this, declaration.name.name, internalName, declaration);
|
||||
var enm = new Enum(this, declaration.name.text, internalName, declaration);
|
||||
enm.namespace = namespace;
|
||||
this.elements.set(internalName, enm);
|
||||
|
||||
@ -576,13 +575,13 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
if (namespace) {
|
||||
if (namespace.members) {
|
||||
if (namespace.members.has(declaration.name.name)) {
|
||||
if (namespace.members.has(declaration.name.text)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
namespace.members = new Map();
|
||||
namespace.members.set(declaration.name.name, enm);
|
||||
namespace.members.set(declaration.name.text, enm);
|
||||
} else if (enm.is(ElementFlags.EXPORTED)) {
|
||||
if (this.exports.has(internalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, declaration.name.range, internalName);
|
||||
@ -597,7 +596,7 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
private initializeEnumValue(declaration: EnumValueDeclaration, enm: Enum): void {
|
||||
var name = declaration.name.name;
|
||||
var name = declaration.name.text;
|
||||
var internalName = declaration.fileLevelInternalName;
|
||||
if (enm.members) {
|
||||
if (enm.members.has(name)) {
|
||||
@ -619,19 +618,19 @@ export class Program extends DiagnosticEmitter {
|
||||
private setExportAndCheckLibrary(name: string, element: Element, identifier: IdentifierExpression): void {
|
||||
this.exports.set(name, element);
|
||||
if (identifier.range.source.isLibrary) { // add global alias
|
||||
if (this.elements.has(identifier.name))
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, identifier.range, identifier.name);
|
||||
if (this.elements.has(identifier.text))
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, identifier.range, identifier.text);
|
||||
else {
|
||||
element.internalName = identifier.name;
|
||||
this.elements.set(identifier.name, element);
|
||||
element.internalName = identifier.text;
|
||||
this.elements.set(identifier.text, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private initializeExport(member: ExportMember, internalPath: string | null, queuedExports: Map<string,QueuedExport>): void {
|
||||
var externalName = member.range.source.internalPath + PATH_DELIMITER + member.externalIdentifier.name;
|
||||
var externalName = member.range.source.internalPath + PATH_DELIMITER + member.externalName.text;
|
||||
if (this.exports.has(externalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalIdentifier.range, externalName);
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalName.range, externalName);
|
||||
return;
|
||||
}
|
||||
var referencedName: string;
|
||||
@ -640,17 +639,17 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
// export local element
|
||||
if (internalPath == null) {
|
||||
referencedName = member.range.source.internalPath + PATH_DELIMITER + member.identifier.name;
|
||||
referencedName = member.range.source.internalPath + PATH_DELIMITER + member.name.text;
|
||||
|
||||
// resolve right away if the element exists
|
||||
if (referencedElement = this.elements.get(referencedName)) {
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalName);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise queue it
|
||||
if (queuedExports.has(externalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalIdentifier.range, externalName);
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalName.range, externalName);
|
||||
return;
|
||||
}
|
||||
queuedExport = new QueuedExport();
|
||||
@ -661,11 +660,11 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
// export external element
|
||||
} else {
|
||||
referencedName = (<string>internalPath) + PATH_DELIMITER + member.identifier.name;
|
||||
referencedName = (<string>internalPath) + PATH_DELIMITER + member.name.text;
|
||||
|
||||
// resolve right away if the export exists
|
||||
if (referencedElement = this.elements.get(referencedName)) {
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalName);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -674,7 +673,7 @@ export class Program extends DiagnosticEmitter {
|
||||
while (queuedExport = queuedExports.get(referencedName)) {
|
||||
if (queuedExport.isReExport) {
|
||||
if (referencedElement = this.exports.get(queuedExport.referencedName)) {
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalName);
|
||||
return;
|
||||
}
|
||||
referencedName = queuedExport.referencedName;
|
||||
@ -683,7 +682,7 @@ export class Program extends DiagnosticEmitter {
|
||||
seen.add(queuedExport);
|
||||
} else {
|
||||
if (referencedElement = this.elements.get(queuedExport.referencedName)) {
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalIdentifier);
|
||||
this.setExportAndCheckLibrary(externalName, referencedElement, member.externalName);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -692,7 +691,7 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
// otherwise queue it
|
||||
if (queuedExports.has(externalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalIdentifier.range, externalName);
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, member.externalName.range, externalName);
|
||||
return;
|
||||
}
|
||||
queuedExport = new QueuedExport();
|
||||
@ -709,7 +708,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
var prototype = new FunctionPrototype(this, declaration.name.name, internalName, declaration, null);
|
||||
var prototype = new FunctionPrototype(this, declaration.name.text, internalName, declaration, null);
|
||||
prototype.namespace = namespace;
|
||||
this.elements.set(internalName, prototype);
|
||||
|
||||
@ -717,13 +716,13 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
if (namespace) {
|
||||
if (namespace.members) {
|
||||
if (namespace.members.has(declaration.name.name)) {
|
||||
if (namespace.members.has(declaration.name.text)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
namespace.members = new Map();
|
||||
namespace.members.set(declaration.name.name, prototype);
|
||||
namespace.members.set(declaration.name.text, prototype);
|
||||
} else if (prototype.is(ElementFlags.EXPORTED)) {
|
||||
if (this.exports.has(internalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, declaration.name.range, internalName);
|
||||
@ -739,7 +738,7 @@ export class Program extends DiagnosticEmitter {
|
||||
for (var i = 0, k = declarations.length; i < k; ++i)
|
||||
this.initializeImport(declarations[i], statement.internalPath, queuedExports, queuedImports);
|
||||
} else if (statement.namespaceName) {
|
||||
var internalName = statement.range.source.internalPath + "/" + statement.namespaceName.name;
|
||||
var internalName = statement.range.source.internalPath + "/" + statement.namespaceName.text;
|
||||
if (this.elements.has(internalName)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, statement.namespaceName.range, internalName);
|
||||
return;
|
||||
@ -755,7 +754,7 @@ export class Program extends DiagnosticEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
var referencedName = internalPath + PATH_DELIMITER + declaration.externalIdentifier.name;
|
||||
var referencedName = internalPath + PATH_DELIMITER + declaration.externalName.text;
|
||||
|
||||
// resolve right away if the export exists
|
||||
if (this.exports.has(referencedName)) {
|
||||
@ -799,7 +798,7 @@ export class Program extends DiagnosticEmitter {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
var prototype = new InterfacePrototype(this, declaration.name.name, internalName, declaration);
|
||||
var prototype = new InterfacePrototype(this, declaration.name.text, internalName, declaration);
|
||||
prototype.namespace = namespace;
|
||||
this.elements.set(internalName, prototype);
|
||||
|
||||
@ -850,7 +849,7 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
var namespace = this.elements.get(internalName);
|
||||
if (!namespace) {
|
||||
namespace = new Namespace(this, declaration.name.name, internalName, declaration);
|
||||
namespace = new Namespace(this, declaration.name.text, internalName, declaration);
|
||||
namespace.namespace = parentNamespace;
|
||||
this.elements.set(internalName, namespace);
|
||||
this.checkInternalDecorators(namespace, declaration);
|
||||
@ -858,13 +857,13 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
if (parentNamespace) {
|
||||
if (parentNamespace.members) {
|
||||
if (parentNamespace.members.has(declaration.name.name)) {
|
||||
if (parentNamespace.members.has(declaration.name.text)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
parentNamespace.members = new Map();
|
||||
parentNamespace.members.set(declaration.name.name, namespace);
|
||||
parentNamespace.members.set(declaration.name.text, namespace);
|
||||
} else if (namespace.is(ElementFlags.EXPORTED)) {
|
||||
if (this.exports.has(internalName)) {
|
||||
this.error(DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0, declaration.name.range, internalName);
|
||||
@ -916,7 +915,7 @@ export class Program extends DiagnosticEmitter {
|
||||
private initializeTypeAlias(declaration: TypeDeclaration, namespace: Element | null = null): void {
|
||||
// type aliases are program globals
|
||||
// TODO: what about namespaced types?
|
||||
var name = declaration.name.name;
|
||||
var name = declaration.name.text;
|
||||
if (this.types.has(name) || this.typeAliases.has(name)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, name);
|
||||
return;
|
||||
@ -934,7 +933,7 @@ export class Program extends DiagnosticEmitter {
|
||||
continue;
|
||||
}
|
||||
|
||||
var global = new Global(this, declaration.name.name, internalName, declaration, /* resolved later */ Type.void);
|
||||
var global = new Global(this, declaration.name.text, internalName, declaration, /* resolved later */ Type.void);
|
||||
global.namespace = namespace;
|
||||
this.elements.set(internalName, global);
|
||||
|
||||
@ -942,13 +941,13 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
if (namespace) {
|
||||
if (namespace.members) {
|
||||
if (namespace.members.has(declaration.name.name)) {
|
||||
if (namespace.members.has(declaration.name.text)) {
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
namespace.members = new Map();
|
||||
namespace.members.set(declaration.name.name, global);
|
||||
namespace.members.set(declaration.name.text, global);
|
||||
} else if (global.is(ElementFlags.EXPORTED)) {
|
||||
if (this.exports.has(internalName))
|
||||
this.error(DiagnosticCode.Duplicate_identifier_0, declaration.name.range, internalName);
|
||||
@ -960,8 +959,8 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
/** Resolves a {@link TypeNode} to a concrete {@link Type}. */
|
||||
resolveType(node: TypeNode, contextualTypeArguments: Map<string,Type> | null = null, reportNotFound: bool = true): Type | null {
|
||||
var globalName = node.identifier.name;
|
||||
var localName = node.range.source.internalPath + PATH_DELIMITER + node.identifier.name;
|
||||
var globalName = node.name.text;
|
||||
var localName = node.range.source.internalPath + PATH_DELIMITER + node.name.text;
|
||||
|
||||
var element: Element | null;
|
||||
|
||||
@ -1008,7 +1007,7 @@ export class Program extends DiagnosticEmitter {
|
||||
return type;
|
||||
|
||||
if (reportNotFound)
|
||||
this.error(DiagnosticCode.Cannot_find_name_0, node.identifier.range, globalName);
|
||||
this.error(DiagnosticCode.Cannot_find_name_0, node.name.range, globalName);
|
||||
|
||||
return null;
|
||||
}
|
||||
@ -1037,7 +1036,7 @@ export class Program extends DiagnosticEmitter {
|
||||
|
||||
/** Resolves an identifier to the element it refers to. */
|
||||
resolveIdentifier(identifier: IdentifierExpression, contextualFunction: Function | null, contextualEnum: Enum | null = null): ResolvedElement | null {
|
||||
var name = identifier.name;
|
||||
var name = identifier.text;
|
||||
|
||||
var element: Element | null;
|
||||
var namespace: Element | null;
|
||||
@ -1086,7 +1085,7 @@ export class Program extends DiagnosticEmitter {
|
||||
var target = resolvedElement.element;
|
||||
|
||||
// at this point we know exactly what the target is, so look up the element within
|
||||
var propertyName = propertyAccess.property.name;
|
||||
var propertyName = propertyAccess.property.text;
|
||||
var targetType: Type;
|
||||
var member: Element | null;
|
||||
|
||||
@ -1608,7 +1607,7 @@ export class FunctionPrototype extends Element {
|
||||
if ((k = this.classTypeArguments.length) != classTypeParameters.length)
|
||||
throw new Error("type argument count mismatch");
|
||||
for (i = 0; i < k; ++i)
|
||||
contextualTypeArguments.set(classTypeParameters[i].identifier.name, this.classTypeArguments[i]);
|
||||
contextualTypeArguments.set(classTypeParameters[i].name.text, this.classTypeArguments[i]);
|
||||
}
|
||||
|
||||
// override call specific contextual type arguments
|
||||
@ -1617,7 +1616,7 @@ export class FunctionPrototype extends Element {
|
||||
if (k != functionTypeParameters.length)
|
||||
throw new Error("type argument count mismatch");
|
||||
for (i = 0; i < k; ++i)
|
||||
contextualTypeArguments.set(functionTypeParameters[i].identifier.name, functionTypeArguments[i]);
|
||||
contextualTypeArguments.set(functionTypeParameters[i].name.text, functionTypeArguments[i]);
|
||||
}
|
||||
|
||||
// resolve parameters
|
||||
@ -1631,7 +1630,7 @@ export class FunctionPrototype extends Element {
|
||||
typeNode = assert(parameterDeclaration.type);
|
||||
var parameterType = this.program.resolveType(typeNode, contextualTypeArguments, true); // reports
|
||||
if (parameterType) {
|
||||
parameters[i] = new Parameter(parameterDeclaration.name.name, parameterType, parameterDeclaration.initializer);
|
||||
parameters[i] = new Parameter(parameterDeclaration.name.text, parameterType, parameterDeclaration.initializer);
|
||||
parameterTypes[i] = parameterType;
|
||||
} else
|
||||
return null;
|
||||
@ -1785,9 +1784,12 @@ export class Function extends Element {
|
||||
case NativeType.F64: temps = this.tempF64s; break;
|
||||
default: throw new Error("concrete type expected");
|
||||
}
|
||||
return temps && temps.length > 0
|
||||
? temps.pop()
|
||||
: this.addLocal(type);
|
||||
if (temps && temps.length) {
|
||||
var ret = temps.pop();
|
||||
ret.type = type;
|
||||
return ret;
|
||||
}
|
||||
return this.addLocal(type);
|
||||
}
|
||||
|
||||
/** Frees the temporary local for reuse. */
|
||||
@ -2023,7 +2025,7 @@ export class ClassPrototype extends Element {
|
||||
if ((k = typeArguments.length) != declaration.typeParameters.length)
|
||||
throw new Error("type argument count mismatch");
|
||||
for (var i = 0; i < k; ++i)
|
||||
contextualTypeArguments.set(declaration.typeParameters[i].identifier.name, typeArguments[i]);
|
||||
contextualTypeArguments.set(declaration.typeParameters[i].name.text, typeArguments[i]);
|
||||
} else if (declaration.typeParameters.length)
|
||||
throw new Error("type argument count mismatch");
|
||||
|
||||
@ -2172,7 +2174,7 @@ export class Class extends Element {
|
||||
if (!this.contextualTypeArguments)
|
||||
this.contextualTypeArguments = new Map();
|
||||
for (i = 0; i < k; ++i)
|
||||
this.contextualTypeArguments.set(typeParameters[i].identifier.name, typeArguments[i]);
|
||||
this.contextualTypeArguments.set(typeParameters[i].name.text, typeArguments[i]);
|
||||
}
|
||||
} else if (typeParameters.length)
|
||||
throw new Error("type argument count mismatch");
|
||||
|
@ -1,9 +1,13 @@
|
||||
(module
|
||||
(type $iv (func (param i32)))
|
||||
(type $v (func))
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(func $scoped/fn (; 0 ;) (type $iv) (param $0 i32)
|
||||
(nop)
|
||||
)
|
||||
(func $start (; 1 ;) (type $v)
|
||||
(local $0 i32)
|
||||
(loop $continue|0
|
||||
(if
|
||||
@ -42,5 +46,8 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
(call $scoped/fn
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -12,3 +12,15 @@ for (let aGlobal /* that shadows */: i32 = 0; aGlobal < 1; ++aGlobal)
|
||||
let /* still not */ aConstant: f32 = 10;
|
||||
}
|
||||
}
|
||||
|
||||
// regression test: reused local should be updated with new requested type
|
||||
function fn(c: i32): void {
|
||||
{
|
||||
let a: bool = 0;
|
||||
}
|
||||
{
|
||||
let b: i32;
|
||||
b = c; // should not issue a conversion warning mentioning 'bool'
|
||||
}
|
||||
}
|
||||
fn(42);
|
||||
|
@ -1,4 +1,5 @@
|
||||
(module
|
||||
(type $iv (func (param i32)))
|
||||
(type $v (func))
|
||||
(global $scoped/aGlobal (mut i32) (i32.const 1))
|
||||
(global $scoped/aConstant i32 (i32.const 3))
|
||||
@ -7,7 +8,28 @@
|
||||
(memory $0 1)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(func $scoped/fn (; 0 ;) (type $iv) (param $0 i32)
|
||||
(local $1 i32)
|
||||
;;@ scoped.ts:18:2
|
||||
(block
|
||||
;;@ scoped.ts:19:4
|
||||
(set_local $1
|
||||
;;@ scoped.ts:19:18
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
;;@ scoped.ts:21:2
|
||||
(block
|
||||
;;@ scoped.ts:22:4
|
||||
(nop)
|
||||
;;@ scoped.ts:23:4
|
||||
(set_local $1
|
||||
;;@ scoped.ts:23:8
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func $start (; 1 ;) (type $v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i64)
|
||||
@ -92,5 +114,10 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
;;@ scoped.ts:26:0
|
||||
(call $scoped/fn
|
||||
;;@ scoped.ts:26:3
|
||||
(i32.const 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user