private TypeInfo getType(String name) { name = name.trim(); int dimensions = 0; while (name.endsWith("[]")) { dimensions++; name = name.substring(0, name.length() - 2); } TypeInfo result; switch (name) { case "boolean": result = context.TypeSystem.BooleanType; break; case "byte": result = context.TypeSystem.ByteType; break; case "char": result = context.TypeSystem.CharType; break; case "short": result = context.TypeSystem.ShortType; break; case "int": result = context.TypeSystem.IntType; break; case "long": result = context.TypeSystem.LongType; break; case "float": result = context.TypeSystem.FloatType; break; case "double": result = context.TypeSystem.DoubleType; break; default: int idx = name.indexOf("."); String prefix; if (idx == -1) { prefix = name; name = null; } else { prefix = name.substring(0, idx); name = name.substring(idx + 1); } var members = context.MemberResolver.resolveName(context.CurrentType, prefix, Query.empty<TypeInfo>()).toList(); if (!members.any()) { if (name == null) { return null; } var packageName = context.MemberResolver.getPackageFromAlias(prefix); if (packageName == null) { if (context.MemberResolver.TypeFinder.getSubPackages(prefix).any() || context.MemberResolver.TypeFinder.getClasses(prefix).any()) { packageName = prefix; } else { return null; } } var found = false; do { idx = name.indexOf('.'); if (idx == -1) { prefix = name; name = null; } else { prefix = name.substring(0, idx); name = name.substring(idx + 1); } foreach (var s in context.MemberResolver.TypeFinder.getSubPackages(packageName)) { if (s.equals(prefix)) { packageName = packageName + '/' + prefix; found = true; break; } } if (!found && !context.MemberResolver.TypeFinder.getClasses(packageName).contains(prefix)) { return null; } } while (name != null && found); result = context.TypeSystem.getType(packageName + '/' + prefix); } else if (members.count() > 1) { return null; } else { result = members.first().Type; } break; } while (dimensions-- > 0) { type = type.ArrayType; } return result; }
private void replaceCref(Element element, bool exception, Iterable<MemberInfo> members, String suffix, String arguments) { if (members.count() > 1 && !members.all(p => p.MemberKind == MemberKind.Method)) { context.addWarning(CompileErrorId.UnresolvedCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); return; } var member = members.first(); switch (member.MemberKind) { case Type: replaceCref(element, exception, member.Type, suffix, arguments); break; case Field: if (exception) { context.addWarning(CompileErrorId.ExpectedExceptionInCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); return; } if (suffix != null || arguments != null) { context.addWarning(CompileErrorId.UnresolvedCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); return; } element.setAttribute("cref", getIdString(member.Field)); break; case Property: if (exception) { context.addWarning(CompileErrorId.ExpectedExceptionInCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); return; } if (suffix != null || arguments != null) { context.addWarning(CompileErrorId.UnresolvedCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); return; } element.setAttribute("cref", getIdString(member.GetAccessor ?? member.SetAccessor)); break; case Method: if (!exception && suffix == null) { if (arguments == null && members.count() == 1) { element.setAttribute("cref", getIdString(member.Method)); return; } else if (arguments != null && arguments.endsWith(")")) { var args = new ArrayList<TypeInfo>(); if (arguments.length() > 2) { arguments = arguments.substring(1, arguments.length() - 1); int idx; while ((idx = arguments.indexOf(',')) != -1) { var name = arguments.substring(0, idx); arguments = arguments.substring(idx + 1); var type = getType(name); if (type == null) { goto failed; } args.add(type); } if (arguments.length() == 0) { goto failed; } var type = getType(arguments); if (type == null) { goto failed; } args.add(type); } foreach (var m in members) { if (m.Method.Parameters.select(p => p.Type).sequenceEqual(args)) { element.setAttribute("cref", getIdString(m.Method)); return; } } } } failed: context.addWarning(CompileErrorId.UnresolvedCref, node, element.getAttribute("cref")); element.setAttribute("cref", "!" + element.getAttribute("cref")); break; default: break; } }