private static void getAllMethods( ClassOrInterface c, TypeDeclaration t, List<MethodWithContainer> members) { for (Declaration d : t.getMembers()) { if (d instanceof Function) { Function m = (Function) d; boolean contains = false; for (MethodWithContainer member : members) { if (member.getMethod().getName().equals(m.getName())) { contains = true; break; } } if (!contains) { members.add(new MethodWithContainer(c, m)); } } } Type et = t.getExtendedType(); if (et != null) { getAllMethods(c, et.getDeclaration(), members); } for (Type st : t.getSatisfiedTypes()) { getAllMethods(c, st.getDeclaration(), members); } }
private void importMembers(Tree.ImportMemberOrType member, Declaration d) { Tree.ImportMemberOrTypeList imtl = member.getImportMemberOrTypeList(); if (imtl != null) { if (d instanceof Value) { Value v = (Value) d; TypeDeclaration td = v.getTypeDeclaration(); if (td.isObjectClass()) { d = td; } } if (d instanceof TypeDeclaration) { Set<String> names = new HashSet<String>(); ImportList til = imtl.getImportList(); TypeDeclaration td = (TypeDeclaration) d; til.setImportedScope(td); List<Tree.ImportMemberOrType> imts = imtl.getImportMemberOrTypes(); for (Tree.ImportMemberOrType imt : imts) { names.add(importMember(imt, td, til)); } if (imtl.getImportWildcard() != null) { importAllMembers(td, names, til); } else if (imts.isEmpty()) { imtl.addError("empty import list", 1020); } } else { imtl.addError("member alias list must follow a type"); } } }
@Override public void visit(Tree.BaseType that) { TypeDeclaration d = that.getDeclarationModel(); if (d != null && d.equals(dec)) { detected = true; } }
static String getDescription(Declaration dec) { String desc = "'" + dec.getName() + "'"; Scope container = dec.getContainer(); if (container instanceof TypeDeclaration) { TypeDeclaration td = (TypeDeclaration) container; desc += " in '" + td.getName() + "'"; } return desc; }
private static boolean isLegalAliasFreeImport(Declaration dec, Declaration importedDec) { if (importedDec instanceof Value) { Value value = (Value) importedDec; TypeDeclaration td = value.getTypeDeclaration(); return td.isObjectClass() && td.equals(dec); } else { return false; } }
@Override public Object[] getChildren(Object element) { if (element instanceof CeylonOutlineNode) { if (mode) { boolean includeParameters = !CeylonPlugin.getPreferences().getBoolean(PARAMS_IN_OUTLINES); CeylonOutlineNode node = (CeylonOutlineNode) element; CompilationUnit rootNode = getEditor().getParseController().getLastCompilationUnit(); Node treeNode = Nodes.findNode(rootNode, node.getStartOffset(), node.getEndOffset()); TypeDeclaration td; if (treeNode instanceof ClassOrInterface) { ClassOrInterface ci = (ClassOrInterface) treeNode; td = ci.getDeclarationModel(); } else if (treeNode instanceof ObjectDefinition) { ObjectDefinition od = (ObjectDefinition) treeNode; td = od.getDeclarationModel().getTypeDeclaration(); } else { return super.getChildren(element); } List<Declaration> list = new ArrayList<Declaration>(); String filter = getFilterText().getText(); for (int i = 0; i < filter.length(); i++) { char ch = filter.charAt(i); if (ch == '*' || i > 0 && Character.isUpperCase(ch)) { filter = filter.substring(0, i); break; } } Collection<DeclarationWithProximity> members = td.getMatchingMemberDeclarations(rootNode.getUnit(), td, filter, 0, null).values(); for (DeclarationWithProximity dwp : members) { for (Declaration dec : overloads(dwp.getDeclaration())) { if (!(dec instanceof TypeParameter)) { if (includeParameters || !dec.isParameter()) { list.add(dec); } } } } if (!lexicalSortingAction.isChecked()) { Collections.sort( list, new Comparator<Declaration>() { public int compare(Declaration x, Declaration y) { String xn = x.getContainer().getQualifiedNameString(); String yn = y.getContainer().getQualifiedNameString(); return xn.compareTo(yn); } }); } return list.toArray(); } else { return super.getChildren(element); } } else { return null; } }
public static Declaration extractAnonymousClassIfRequired(Declaration d) { if (d instanceof Value) { Value value = (Value) d; TypeDeclaration typeDeclaration = value.getTypeDeclaration(); if (typeDeclaration instanceof Class && typeDeclaration.isAnonymous()) { return typeDeclaration; } } return d; }
public static String[] getAssignableLiterals(Type type, Unit unit) { TypeDeclaration dtd = unit.getDefiniteType(type).getDeclaration(); if (dtd instanceof Class) { if (dtd.isInteger()) { return new String[] {"0", "1", "2"}; } if (dtd.isByte()) { return new String[] {"0.byte", "1.byte"}; } else if (dtd.isFloat()) { return new String[] {"0.0", "1.0", "2.0"}; } else if (dtd.isString()) { return new String[] {"\"\"", "\"\"\"\"\"\""}; } else if (dtd.isCharacter()) { return new String[] {"' '", "'\\n'", "'\\t'"}; } else { return new String[0]; } } else if (dtd instanceof Interface) { if (dtd.isIterable()) { return new String[] {"{}"}; } else if (dtd.isSequential() || dtd.isEmpty()) { return new String[] {"[]"}; } else { return new String[0]; } } else { return new String[0]; } }
public static Declaration getRefinedDeclaration(Declaration declaration) { // Reproduces the algorithm used to build the type hierarchy // first walk up the superclass hierarchy if (declaration.isClassOrInterfaceMember() && declaration.isShared()) { TypeDeclaration dec = (TypeDeclaration) declaration.getContainer(); List<Type> signature = getSignature(declaration); Declaration refined = declaration.getRefinedDeclaration(); while (dec != null) { Type extended = dec.getExtendedType(); if (extended != null) { TypeDeclaration superDec = extended.getDeclaration(); Declaration superMemberDec = superDec.getDirectMember(declaration.getName(), signature, false); if (superMemberDec != null) { Declaration superRefined = superMemberDec.getRefinedDeclaration(); if (superRefined != null && refined != null && !isAbstraction(superMemberDec) && superRefined.equals(refined)) { return superMemberDec; } } dec = superDec; } else { dec = null; } } // now look at the very top of the hierarchy, even if it is an interface Declaration refinedDeclaration = refined; if (refinedDeclaration != null && !declaration.equals(refinedDeclaration)) { List<Declaration> directlyInheritedMembers = getInterveningRefinements( declaration.getName(), signature, refinedDeclaration, (TypeDeclaration) declaration.getContainer(), (TypeDeclaration) refinedDeclaration.getContainer()); directlyInheritedMembers.remove(refinedDeclaration); // TODO: do something for the case of // multiple intervening interfaces? if (directlyInheritedMembers.size() == 1) { // exactly one intervening interface return directlyInheritedMembers.get(0); } else { // no intervening interfaces return refinedDeclaration; } } } return null; }
static String defaultValue(Unit unit, Type t) { if (isTypeUnknown(t)) { return "nothing"; } if (unit.isOptionalType(t)) { return "null"; } if (t.isTypeAlias() || t.isClassOrInterface() && t.getDeclaration().isAlias()) { return defaultValue(unit, t.getExtendedType()); } if (t.isClass()) { TypeDeclaration c = t.getDeclaration(); if (c.equals(unit.getBooleanDeclaration())) { return "false"; } else if (c.equals(unit.getIntegerDeclaration())) { return "0"; } else if (c.equals(unit.getFloatDeclaration())) { return "0.0"; } else if (c.equals(unit.getStringDeclaration())) { return "\"\""; } else if (c.equals(unit.getByteDeclaration())) { return "0.byte"; } else if (c.equals(unit.getTupleDeclaration())) { final int minimumLength = unit.getTupleMinimumLength(t); final List<Type> tupleTypes = unit.getTupleElementTypes(t); final StringBuilder sb = new StringBuilder(); for (int i = 0; i < minimumLength; i++) { sb.append(sb.length() == 0 ? "[" : ", "); Type currentType = tupleTypes.get(i); if (unit.isSequentialType(currentType)) { currentType = unit.getSequentialElementType(currentType); } sb.append(defaultValue(unit, currentType)); } sb.append(']'); return sb.toString(); } else if (unit.isSequentialType(t)) { final StringBuilder sb = new StringBuilder(); sb.append('['); if (!unit.getEmptyType().isSubtypeOf(t)) { sb.append(defaultValue(unit, unit.getSequentialElementType(t))); } sb.append(']'); return sb.toString(); } else if (unit.isIterableType(t)) { final StringBuilder sb = new StringBuilder(); sb.append('{'); if (!unit.getEmptyType().isSubtypeOf(t)) { sb.append(defaultValue(unit, unit.getIteratedType(t))); } sb.append('}'); return sb.toString(); } else { return "nothing"; } } else { return "nothing"; } }
@Override public void visit(Tree.TypedDeclaration that) { super.visit(that); Tree.Identifier id = that.getIdentifier(); if (id != null) { Type type = that.getType().getTypeModel(); if (type != null) { TypeDeclaration td = type.getDeclaration(); if ((td instanceof ClassOrInterface || td instanceof TypeParameter) && td.equals(declaration)) { String text = id.getText(); String name = declaration.getName(); if (text.equalsIgnoreCase(name) || text.endsWith(name)) { identifiers.add(id); } } } } }
static boolean isIgnoredLanguageModuleType(TypeDeclaration td) { return !td.isObject() && !td.isAnything() && !td.isString() && !td.isInteger() && !td.isCharacter() && !td.isFloat() && !td.isBoolean(); }
private void importAllMembers( TypeDeclaration importedType, Set<String> ignoredMembers, ImportList til) { for (Declaration dec : importedType.getMembers()) { if (dec.isShared() && (dec.isStaticallyImportable() || isConstructor(dec)) && isResolvable(dec) && !ignoredMembers.contains(dec.getName())) { addWildcardImport(til, dec, importedType); } } }
/** * See #547 - a generic actual method that has different names in its type parameters as the one * it's refining, can receive the type arguments of the parent instead. */ static void addParentMethodTypeParameters(final Function m, final GenerateJsVisitor gen) { List<TypeParameter> tps = m.getTypeParameters(); if (m.isActual() && tps != null && !tps.isEmpty()) { // This gives us the root declaration Function sm = (Function) m.getRefinedDeclaration(); for (int i = 0; i < tps.size(); i++) { boolean end = false; end |= copyMissingTypeParameters(m, sm, i, true, gen); // We still need to find intermediate declarations if (m.isClassOrInterfaceMember()) { final Set<Declaration> decs = new HashSet<Declaration>(); decs.add(sm); decs.add(m); // This gives us the containing type TypeDeclaration cont = ModelUtil.getContainingClassOrInterface(m); for (TypeDeclaration sup : cont.getSupertypeDeclarations()) { Declaration d = sup.getDirectMember(m.getName(), null, false); if (d instanceof Function && !decs.contains(d)) { decs.add(d); end |= copyMissingTypeParameters(m, (Function) d, i, false, gen); } } for (Type sup : cont.getSatisfiedTypes()) { Declaration d = sup.getDeclaration().getDirectMember(m.getName(), null, false); if (d instanceof Function && !decs.contains(d)) { decs.add(d); end |= copyMissingTypeParameters(m, (Function) d, i, false, gen); } } } if (end) { gen.endLine(true); } } } }
private String importMember(Tree.ImportMemberOrType member, TypeDeclaration td, ImportList il) { Tree.Identifier id = member.getIdentifier(); if (id == null) { return null; } Import i = new Import(); member.setImportModel(i); Tree.Alias alias = member.getAlias(); String name = name(id); if (alias == null) { i.setAlias(name); } else { i.setAlias(name(alias.getIdentifier())); } Declaration m = td.getMember(name, null, false); if (m == null) { String correction = correct(td, null, unit, name); String message = correction == null ? "" : " (did you mean '" + correction + "'?)"; id.addError( "imported declaration not found: '" + name + "' of '" + td.getName() + "'" + message, 100); unit.getUnresolvedReferences().add(id); } else { List<Declaration> members = m.getContainer().getMembers(); for (Declaration d : members) { String dn = d.getName(); if (dn != null && dn.equals(name) && !d.sameKind(m) && !d.isAnonymous()) { // crazy interop cases like isOpen() + open() id.addError("ambiguous member declaration: '" + name + "' of '" + td.getName() + "'"); return null; } } if (!m.isShared()) { id.addError( "imported declaration is not shared: '" + name + "' of '" + td.getName() + "'", 400); } else if (!declaredInPackage(m, unit)) { if (m.isPackageVisibility()) { id.addError( "imported package private declaration is not visible: '" + name + "' of '" + td.getName() + "'"); } else if (m.isProtectedVisibility()) { id.addError( "imported protected declaration is not visible: '" + name + "' of '" + td.getName() + "'"); } } i.setTypeDeclaration(td); if (!m.isStaticallyImportable() && !isToplevelClassConstructor(td, m) && !isToplevelAnonymousClass(m.getContainer())) { if (alias == null) { member.addError("does not specify an alias"); } } i.setDeclaration(m); member.setDeclarationModel(m); if (il.hasImport(m)) { id.addError("already imported: '" + name + "' of '" + td.getName() + "'"); } else { if (m.isStaticallyImportable() || isToplevelClassConstructor(td, m) || isToplevelAnonymousClass(m.getContainer())) { if (!checkForHiddenToplevel(id, i, alias)) { addImport(member, il, i); } } else { addMemberImport(member, il, i); } } checkAliasCase(alias, m); } if (m != null) { importMembers(member, m); } // imtl.addError("member aliases may not have member aliases"); return name; }
@Deprecated // replaced by RefineFormalMembersQuickFix.ceylon private void refineFormalMembers(IDocument document) throws ExecutionException { if (rootNode == null) return; TextChange change = new DocumentChange("Refine Members", document); change.setEdit(new MultiTextEdit()); // TODO: copy/pasted from CeylonQuickFixAssistant Tree.Body body; int offset; if (node instanceof Tree.ClassDefinition) { ClassDefinition classDefinition = (Tree.ClassDefinition) node; body = classDefinition.getClassBody(); offset = -1; } else if (node instanceof Tree.InterfaceDefinition) { Tree.InterfaceDefinition interfaceDefinition = (Tree.InterfaceDefinition) node; body = interfaceDefinition.getInterfaceBody(); offset = -1; } else if (node instanceof Tree.ObjectDefinition) { Tree.ObjectDefinition objectDefinition = (Tree.ObjectDefinition) node; body = objectDefinition.getClassBody(); offset = -1; } else if (node instanceof Tree.ObjectExpression) { Tree.ObjectExpression objectExpression = (Tree.ObjectExpression) node; body = objectExpression.getClassBody(); offset = -1; } else if (node instanceof Tree.ClassBody || node instanceof Tree.InterfaceBody) { body = (Tree.Body) node; IEditorPart editor = getCurrentEditor(); if (editor instanceof CeylonEditor) { CeylonEditor ce = (CeylonEditor) editor; offset = ce.getSelection().getOffset(); } else { offset = -1; } } else { return; } if (body == null) { return; } boolean isInterface = body instanceof Tree.InterfaceBody; List<Tree.Statement> statements = body.getStatements(); String indent; // String bodyIndent = getIndent(body, document); String bodyIndent = utilJ2C().indents().getIndent(node, document); String delim = utilJ2C().indents().getDefaultLineDelimiter(document); if (statements.isEmpty()) { indent = delim + bodyIndent + utilJ2C().indents().getDefaultIndent(); if (offset < 0) { offset = body.getStartIndex() + 1; } } else { Tree.Statement statement = statements.get(statements.size() - 1); indent = delim + utilJ2C().indents().getIndent(statement, document); if (offset < 0) { offset = statement.getEndIndex(); } } StringBuilder result = new StringBuilder(); Set<Declaration> already = new HashSet<Declaration>(); ClassOrInterface ci = (ClassOrInterface) node.getScope(); Unit unit = node.getUnit(); Set<String> ambiguousNames = new HashSet<String>(); // TODO: does not return unrefined overloaded // versions of a method with one overlaad // already refined Collection<DeclarationWithProximity> proposals = ci.getMatchingMemberDeclarations(unit, ci, "", 0).values(); for (DeclarationWithProximity dwp : proposals) { Declaration dec = dwp.getDeclaration(); for (Declaration d : overloads(dec)) { try { if (d.isFormal() && ci.isInheritedFromSupertype(d)) { appendRefinementText(isInterface, indent, result, ci, unit, d); importProposals().importSignatureTypes(d, rootNode, already); ambiguousNames.add(d.getName()); } } catch (Exception e) { e.printStackTrace(); } } } for (TypeDeclaration superType : ci.getSupertypeDeclarations()) { for (Declaration m : superType.getMembers()) { try { if (m.getName() != null && m.isShared()) { Declaration r = ci.getMember(m.getName(), null, false); if ((r == null || !r.refines(m) && !r.getContainer().equals(ci)) && ambiguousNames.add(m.getName())) { appendRefinementText(isInterface, indent, result, ci, unit, m); importProposals().importSignatureTypes(m, rootNode, already); } } } catch (Exception e) { e.printStackTrace(); } } } try { if (document.getChar(offset) == '}' && result.length() > 0) { result.append(delim).append(bodyIndent); } } catch (BadLocationException e) { e.printStackTrace(); } importProposals().applyImports(change, already, rootNode, document); change.addEdit(new InsertEdit(offset, result.toString())); change.initializeValidationData(null); try { getWorkspace().run(new PerformChangeOperation(change), new NullProgressMonitor()); } catch (CoreException ce) { ce.printStackTrace(); } }