Skip to content

Commit bc7a027

Browse files
committed
Merge remote-tracking branch 'origin/master' into release
2 parents d3cde4c + 6adbbd9 commit bc7a027

11 files changed

+125
-53
lines changed

src/compiler.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -695,8 +695,9 @@ export class Compiler extends DiagnosticEmitter {
695695

696696
// traverse instances
697697
case ElementKind.FUNCTION_PROTOTYPE: {
698-
let functionInstances = (<FunctionPrototype>element).instances;
699-
if (functionInstances) {
698+
let functionPrototype = <FunctionPrototype>element;
699+
let functionInstances = functionPrototype.instances;
700+
if (functionInstances !== null && functionInstances.size > 0) {
700701
// TODO: for (let instance of instances.values()) {
701702
for (let _values = Map_values(functionInstances), i = 0, k = _values.length; i < k; ++i) {
702703
let instance = unchecked(_values[i]);
@@ -707,12 +708,18 @@ export class Compiler extends DiagnosticEmitter {
707708
}
708709
this.ensureModuleExport(instanceName, instance, prefix);
709710
}
711+
} else if (functionPrototype.is(CommonFlags.GENERIC)) {
712+
this.warning(
713+
DiagnosticCode.Exported_generic_function_or_class_has_no_concrete_instances,
714+
functionPrototype.identifierNode.range
715+
);
710716
}
711717
break;
712718
}
713719
case ElementKind.CLASS_PROTOTYPE: {
714-
let classInstances = (<ClassPrototype>element).instances;
715-
if (classInstances) {
720+
let classPrototype = <ClassPrototype>element;
721+
let classInstances = classPrototype.instances;
722+
if (classInstances !== null && classInstances.size > 0) {
716723
// TODO: for (let instance of instances.values()) {
717724
for (let _values = Map_values(classInstances), i = 0, k = _values.length; i < k; ++i) {
718725
let instance = unchecked(_values[i]);
@@ -723,6 +730,11 @@ export class Compiler extends DiagnosticEmitter {
723730
}
724731
this.ensureModuleExport(instanceName, instance, prefix);
725732
}
733+
} else if (classPrototype.is(CommonFlags.GENERIC)) {
734+
this.warning(
735+
DiagnosticCode.Exported_generic_function_or_class_has_no_concrete_instances,
736+
classPrototype.identifierNode.range
737+
);
726738
}
727739
break;
728740
}

src/diagnosticMessages.generated.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export enum DiagnosticCode {
2020
Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201,
2121
Type_0_cannot_be_changed_to_type_1 = 202,
2222
Operation_0_cannot_be_applied_to_type_1 = 203,
23-
Basic_type_0_cannot_be_nullable = 204,
23+
Type_0_cannot_be_nullable = 204,
2424
Cannot_export_a_mutable_global = 205,
2525
Mutable_value_cannot_be_inlined = 206,
2626
Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
@@ -48,6 +48,7 @@ export enum DiagnosticCode {
4848
Property_0_only_has_a_setter_and_is_missing_a_getter = 229,
4949
_0_keyword_cannot_be_used_here = 230,
5050
A_class_with_a_constructor_explicitly_returning_something_else_than_this_must_be_final = 231,
51+
Exported_generic_function_or_class_has_no_concrete_instances = 232,
5152
Type_0_is_cyclic_Module_will_include_deferred_garbage_collection = 900,
5253
Importing_the_table_disables_some_indirect_call_optimizations = 901,
5354
Exporting_the_table_disables_some_indirect_call_optimizations = 902,
@@ -193,7 +194,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
193194
case 201: return "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.";
194195
case 202: return "Type '{0}' cannot be changed to type '{1}'.";
195196
case 203: return "Operation '{0}' cannot be applied to type '{1}'.";
196-
case 204: return "Basic type '{0}' cannot be nullable.";
197+
case 204: return "Type '{0}' cannot be nullable.";
197198
case 205: return "Cannot export a mutable global.";
198199
case 206: return "Mutable value cannot be inlined.";
199200
case 207: return "Unmanaged classes cannot extend managed classes and vice-versa.";
@@ -221,6 +222,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
221222
case 229: return "Property '{0}' only has a setter and is missing a getter.";
222223
case 230: return "'{0}' keyword cannot be used here.";
223224
case 231: return "A class with a constructor explicitly returning something else than 'this' must be '@final'.";
225+
case 232: return "Exported generic function or class has no concrete instances.";
224226
case 900: return "Type '{0}' is cyclic. Module will include deferred garbage collection.";
225227
case 901: return "Importing the table disables some indirect call optimizations.";
226228
case 902: return "Exporting the table disables some indirect call optimizations.";

src/diagnosticMessages.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.": 201,
1414
"Type '{0}' cannot be changed to type '{1}'.": 202,
1515
"Operation '{0}' cannot be applied to type '{1}'.": 203,
16-
"Basic type '{0}' cannot be nullable.": 204,
16+
"Type '{0}' cannot be nullable.": 204,
1717
"Cannot export a mutable global.": 205,
1818
"Mutable value cannot be inlined.": 206,
1919
"Unmanaged classes cannot extend managed classes and vice-versa.": 207,
@@ -41,6 +41,7 @@
4141
"Property '{0}' only has a setter and is missing a getter.": 229,
4242
"'{0}' keyword cannot be used here.": 230,
4343
"A class with a constructor explicitly returning something else than 'this' must be '@final'.": 231,
44+
"Exported generic function or class has no concrete instances.": 232,
4445

4546
"Type '{0}' is cyclic. Module will include deferred garbage collection.": 900,
4647
"Importing the table disables some indirect call optimizations.": 901,

src/parser.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ export class Parser extends DiagnosticEmitter {
155155
var statements = source.statements;
156156
while (!tn.skip(Token.ENDOFFILE)) {
157157
let statement = this.parseTopLevelStatement(tn, null);
158-
if (statement) statements.push(statement);
158+
if (statement) {
159+
statements.push(statement);
160+
} else {
161+
this.skipStatement(tn);
162+
}
159163
}
160164
}
161165

@@ -538,6 +542,12 @@ export class Parser extends DiagnosticEmitter {
538542
Node.createSimpleTypeName("bool", tn.range()), [], false, tn.range(startPos, tn.pos)
539543
);
540544

545+
// 'null'
546+
} else if (token == Token.NULL) {
547+
type = Node.createNamedType(
548+
Node.createSimpleTypeName("null", tn.range()), [], false, tn.range(startPos, tn.pos)
549+
);
550+
541551
// StringLiteral
542552
} else if (token == Token.STRINGLITERAL) {
543553
tn.readString();
@@ -550,7 +560,6 @@ export class Parser extends DiagnosticEmitter {
550560
let name = this.parseTypeName(tn);
551561
if (!name) return null;
552562
let parameters: TypeNode[] | null = null;
553-
let nullable = false;
554563

555564
// Name<T>
556565
if (tn.skip(Token.LESSTHAN)) {
@@ -570,31 +579,33 @@ export class Parser extends DiagnosticEmitter {
570579
return null;
571580
}
572581
}
573-
// ... | null
574-
while (tn.skip(Token.BAR)) {
575-
if (tn.skip(Token.NULL)) {
576-
nullable = true;
577-
} else {
578-
if (!suppressErrors) {
579-
this.error(
580-
DiagnosticCode._0_expected,
581-
tn.range(tn.pos), "null"
582-
);
583-
}
584-
return null;
585-
}
586-
}
587582
if (!parameters) parameters = [];
588-
type = Node.createNamedType(name, parameters, nullable, tn.range(startPos, tn.pos));
583+
type = Node.createNamedType(name, parameters, false, tn.range(startPos, tn.pos));
589584
} else {
590585
if (!suppressErrors) {
591586
this.error(
592-
DiagnosticCode.Identifier_expected,
587+
DiagnosticCode.Type_expected,
593588
tn.range()
594589
);
595590
}
596591
return null;
597592
}
593+
// ... | null
594+
while (tn.skip(Token.BAR)) {
595+
if (tn.skip(Token.NULL)) {
596+
type.isNullable = true;
597+
} else {
598+
let notNullStart = tn.pos;
599+
let notNull = this.parseType(tn, false, true);
600+
if (!suppressErrors) {
601+
this.error(
602+
DiagnosticCode._0_expected,
603+
notNull ? notNull.range : tn.range(notNullStart), "null"
604+
);
605+
}
606+
return null;
607+
}
608+
}
598609
// ... [][]
599610
while (tn.skip(Token.OPENBRACKET)) {
600611
let bracketStart = tn.tokenPos;

src/resolver.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class Resolver extends DiagnosticEmitter {
205205
if (type.is(TypeFlags.REFERENCE)) return type.asNullable();
206206
if (reportMode == ReportMode.REPORT) {
207207
this.error(
208-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
208+
DiagnosticCode.Type_0_cannot_be_nullable,
209209
node.range, type.toString()
210210
);
211211
}
@@ -238,7 +238,7 @@ export class Resolver extends DiagnosticEmitter {
238238
if (node.isNullable) {
239239
if (reportMode == ReportMode.REPORT) {
240240
this.error(
241-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
241+
DiagnosticCode.Type_0_cannot_be_nullable,
242242
node.range, element.name + "/i32"
243243
);
244244
}
@@ -283,7 +283,7 @@ export class Resolver extends DiagnosticEmitter {
283283
if (!type.is(TypeFlags.REFERENCE)) {
284284
if (reportMode == ReportMode.REPORT) {
285285
this.error(
286-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
286+
DiagnosticCode.Type_0_cannot_be_nullable,
287287
nameNode.range, nameNode.identifier.text
288288
);
289289
}
@@ -333,7 +333,7 @@ export class Resolver extends DiagnosticEmitter {
333333
if (!type.is(TypeFlags.REFERENCE)) {
334334
if (reportMode == ReportMode.REPORT) {
335335
this.error(
336-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
336+
DiagnosticCode.Type_0_cannot_be_nullable,
337337
nameNode.range, nameNode.identifier.text
338338
);
339339
}
@@ -2716,6 +2716,15 @@ export class Resolver extends DiagnosticEmitter {
27162716
reportMode
27172717
);
27182718
if (!parameterType) return null;
2719+
if (parameterType == Type.void) {
2720+
if (reportMode == ReportMode.REPORT) {
2721+
this.error(
2722+
DiagnosticCode.Type_expected,
2723+
typeNode.range
2724+
);
2725+
}
2726+
return null;
2727+
}
27192728
parameterTypes[i] = parameterType;
27202729
parameterNames[i] = parameterDeclaration.name.text;
27212730
}
@@ -3078,6 +3087,15 @@ export class Resolver extends DiagnosticEmitter {
30783087
instance.contextualTypeArguments,
30793088
reportMode
30803089
);
3090+
if (fieldType == Type.void) {
3091+
if (reportMode == ReportMode.REPORT) {
3092+
this.error(
3093+
DiagnosticCode.Type_expected,
3094+
fieldTypeNode.range
3095+
);
3096+
}
3097+
break;
3098+
}
30813099
}
30823100
if (!fieldType) break; // did report above
30833101
let fieldInstance = new Field(fieldPrototype, instance, fieldType);

0 commit comments

Comments
 (0)