| 693 | | _validIsNames = ['fake', 'shared', 'virtual', 'nonvirtual', 'override', 'new', 'public', 'protected', 'private', 'internal', 'abstract'] |
| | 693 | _validIsNames = ['fake', 'shared', 'virtual', 'nonvirtual', 'override', 'new', 'public', 'protected', 'private', 'internal', 'abstract', 'partial'] |
| 1030 | | def _nameSpaceAddDecl(ns as NameSpace, decl as INameSpaceMember) |
| 1031 | | if ns.declForName(decl.name) |
| 1032 | | .throwError((decl to dynamic).token to IToken, 'The namespace "[ns.fullName]" already contains a declaration named "[decl.name]".') # TODO: give an "error" for the location |
| 1033 | | if ns.unifiedNameSpace.declForName(decl.name) |
| 1034 | | .throwError((decl to dynamic).token to IToken, 'The namespace "[ns.fullName]" already contains a declaration named "[decl.name]" in another file.') # TODO: give an "error" for the location |
| | 1030 | def _nameSpaceAddDecl(ns as NameSpace, decl as INameSpaceMember) as INameSpaceMember |
| | 1031 | """ |
| | 1032 | Adds the decl to the given namespace or throws an error for duplicate declarations. |
| | 1033 | Also, handles `partial` classes and structs. |
| | 1034 | Returns the same declaration, or in the case of `partial`, the original declaration. |
| | 1035 | """ |
| | 1036 | # TODO: complain if inheritance or is-names are different. at least for inheritance, that needs to be done post-parsing |
| | 1037 | checkForDups = true |
| | 1038 | if 'partial' in decl.isNames |
| | 1039 | if decl inherits Box |
| | 1040 | if not (decl inherits Class or decl inherits Struct) |
| | 1041 | .throwError(decl.token, '[Utils.capped(decl.englishName)] cannot be "partial".') |
| | 1042 | checkForDups = false |
| | 1043 | otherDecl = ns.unifiedNameSpace.declForName(decl.name) |
| | 1044 | if otherDecl |
| | 1045 | if otherDecl.getType is not decl.getType |
| | 1046 | .throwError(decl.token, 'The other partial declaration is a "[otherDecl.englishName]", not a "[decl.englishName]".') |
| | 1047 | if 'partial' not in otherDecl.isNames |
| | 1048 | .throwError(decl.token, 'The other declaration is not marked "partial".') |
| | 1049 | otherBox = otherDecl to Box # will always work because of above checks |
| | 1050 | for memberDecl in decl.declsInOrder |
| | 1051 | overload = _overloadIfNeeded(otherBox, memberDecl.name) |
| | 1052 | if overload |
| | 1053 | overload.addMember(memberDecl to BoxMember) |
| | 1054 | else |
| | 1055 | otherBox.addDecl(memberDecl) |
| | 1056 | memberDecl.mergedIntoPartialBox(otherBox) |
| | 1057 | return otherDecl |
| | 1058 | else |
| | 1059 | .throwError(decl.token, '[Utils.capped(decl.englishName)] cannot be "partial".') |
| | 1060 | if checkForDups |
| | 1061 | if ns.declForName(decl.name) |
| | 1062 | .throwError((decl to dynamic).token to IToken, 'The namespace "[ns.fullName]" already contains a declaration named "[decl.name]".') # TODO: give an "error" for the location |
| | 1063 | if ns.unifiedNameSpace.declForName(decl.name) |
| | 1064 | .throwError((decl to dynamic).token to IToken, 'The namespace "[ns.fullName]" already contains a declaration named "[decl.name]" in another file.') # TODO: give an "error" for the location |
| 1177 | | overload as MemberOverload? |
| 1178 | | other = curBox.declForName(name) |
| 1179 | | if other |
| 1180 | | if other inherits MemberOverload |
| 1181 | | overload = other |
| 1182 | | else if other inherits AbstractMethod |
| 1183 | | overload = MemberOverload(other) |
| 1184 | | curBox.registerOverload(overload to !) |
| 1185 | | else |
| 1186 | | .throwError('There is already another class member with the name "[name]".') # TODO list its location and possibly what it is |
| 1187 | | else |
| 1188 | | other = curBox.declForName(name) # TODO: should be a CI there for case-insensitive |
| 1189 | | if other |
| 1190 | | .throwError('There is already another class member with the name "[other.name]". You must differentiate member names by more than just case.') |
| 1191 | | if name[0] in _uppercaseLetters |
| 1192 | | .recordError('Method names must start with lowercase letters. ([name])') |
| | 1208 | overload = _overloadIfNeeded(curBox, name) # also checks for various errors |
| | 3194 | def _overloadIfNeeded(box as Box, name as String) as MemberOverload? |
| | 3195 | """ |
| | 3196 | Creates an overload for a new member going into box--if needed. |
| | 3197 | May throw various appropriate errors. |
| | 3198 | """ |
| | 3199 | overload as MemberOverload? |
| | 3200 | other = box.declForName(name) |
| | 3201 | if other |
| | 3202 | if other inherits MemberOverload |
| | 3203 | overload = other |
| | 3204 | else if other inherits AbstractMethod or other inherits ProperDexer # CC: make this method generic on this type |
| | 3205 | overload = MemberOverload(other to BoxMember) |
| | 3206 | box.registerOverload(overload to !) |
| | 3207 | else |
| | 3208 | .throwError('There is already another class member with the name "[name]".') # TODO list its location and possibly what it is |
| | 3209 | else |
| | 3210 | other = box.declForName(name) # TODO: should be a CI there for case-insensitive |
| | 3211 | if other |
| | 3212 | .throwError('There is already another class member with the name "[other.name]". You must differentiate member names by more than just case.') |
| | 3213 | if name[0] in _uppercaseLetters |
| | 3214 | .recordError('Method names must start with lowercase letters. ([name])') |
| | 3215 | return overload |
| | 3216 | |