diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index 25ef024ad..469ace5c9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -616,17 +616,17 @@ public final class AbcIndexing { return classNames; } - public Set getClassTraitNames(GraphTargetItem cls, ABC abc, Integer scriptIndex, boolean getStatic, boolean getInstance, boolean getInheritance) { + public void getClassTraits(GraphTargetItem cls, ABC abc, Integer scriptIndex, boolean getStatic, boolean getInstance, boolean getInheritance, List ret, List staticRet) { ClassIndex ci = findClass(cls, abc, scriptIndex); if (ci == null) { - return new LinkedHashSet<>(); + return; } - Set ret = new LinkedHashSet<>(); - getClassIndexTraitNames(ret, ci, getStatic, getInstance, getInheritance); - return ret; + ret.clear(); + staticRet.clear(); + getClassIndexTraitNames(ret, staticRet, ci, getStatic, getInstance, getInheritance, new HashSet<>()); } - private void getClassIndexTraitNames(Set ret, ClassIndex ci, boolean getStatic, boolean getInstance, boolean getInheritance) { + private void getClassIndexTraitNames(List ret, List staticRet, ClassIndex ci, boolean getStatic, boolean getInstance, boolean getInheritance, Set used) { GraphTargetItem ciName = multinameToType(ci.abc.instance_info.get(ci.index).name_index, ci.abc.constants); boolean isObject = ciName.equals(new TypeItem("Object")); @@ -643,9 +643,16 @@ public final class AbcIndexing { } if (nsKind == Namespace.KIND_PRIVATE || nsKind == Namespace.KIND_PROTECTED || nsKind == Namespace.KIND_STATIC_PROTECTED) { continue; - } - if (Objects.equals(def.parent, ciName)) { - ret.add(def.propName); + } + if (Objects.equals(def.parent, ciName)) { + if (used.contains(def.propName)) { + continue; + } + used.add(def.propName); + + + ret.add(def); + staticRet.add(false); } } } @@ -662,17 +669,23 @@ public final class AbcIndexing { continue; } if (Objects.equals(def.parent, ciName)) { - ret.add("static::" + def.propName); + if (used.contains(def.propName)) { + continue; + } + used.add(def.propName); + ret.add(def); + staticRet.add(true); } } } - if (getInheritance && ci.parent != null) { - getClassIndexTraitNames(ret, ci.parent, getStatic, getInstance, getInheritance); - } if (parent != null) { - parent.getClassIndexTraitNames(ret, ci, getStatic, getInstance, getInheritance); + parent.getClassIndexTraitNames(ret, staticRet, ci, getStatic, getInstance, getInheritance, used); } + + if (getInheritance && ci.parent != null) { + getClassIndexTraitNames(ret, staticRet, ci.parent, getStatic, getInstance, getInheritance, used); + } } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java index 4a29aef92..6031a2e9c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3SimpleParser.java @@ -2310,11 +2310,11 @@ public class ActionScript3SimpleParser implements SimpleParser { Map> externalTraitKeyToReference, Map separatorPosToType, Map separatorIsStatic, - Map> localTypeTraitNames, + Map> localTypeTraits, Map definitionToType, Map definitionToCallType, Integer caretPosition, - List variableSuggestions + List variableSuggestions ) throws SimpleParseException, IOException, InterruptedException { List> allOpenedNamespaces = new ArrayList<>(); Reference sinitNeedsActivation = new Reference<>(false); @@ -2334,7 +2334,7 @@ public class ActionScript3SimpleParser implements SimpleParser { //Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex); throw new SimpleParseException(str, ex.line); } - SimpleParser.parseVariablesList(vars, definitionPosToReferences, referenceToDefinition, errors, true, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, separatorIsStatic, localTypeTraitNames, definitionToType, definitionToCallType, caretPosition, variableSuggestions); + SimpleParser.parseVariablesList(vars, definitionPosToReferences, referenceToDefinition, errors, true, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, separatorIsStatic, localTypeTraits, definitionToType, definitionToCallType, caretPosition, variableSuggestions); } /** diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java index e7071e0bf..6b173571b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2SimpleParser.java @@ -1595,11 +1595,11 @@ public class ActionScript2SimpleParser implements SimpleParser { Map> externalTraitKeyToReference, Map separatorPosToType, Map separatorIsStatic, - Map> localTypeTraitNames, + Map> localTypeTraits, Map definitionToType, Map definitionToCallType, Integer caretPosition, - List variableSuggestions + List variableSuggestions ) throws SimpleParseException, IOException, InterruptedException { List vars = new ArrayList<>(); @@ -1690,7 +1690,7 @@ public class ActionScript2SimpleParser implements SimpleParser { } catch (ActionParseException ex) { errors.add(new SimpleParseException(ex.getMessage(), ex.line, ex.position)); } - SimpleParser.parseVariablesList(vars, definitionPosToReferences, referenceToDefinition, errors, false, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, separatorIsStatic, localTypeTraitNames, definitionToType, definitionToCallType, caretPosition, variableSuggestions); + SimpleParser.parseVariablesList(vars, definitionPosToReferences, referenceToDefinition, errors, false, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, separatorIsStatic, localTypeTraits, definitionToType, definitionToCallType, caretPosition, variableSuggestions); } private void versionRequired(List errors, ParsedSymbol s, int min) throws SimpleParseException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/LinkHandler.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/LinkHandler.java index b8af5ad97..2cc90121a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/LinkHandler.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/LinkHandler.java @@ -40,5 +40,5 @@ public interface LinkHandler { public void handleTraitLink(Path className, String traitName); - public List getClassTraitNames(Path className, boolean getStatic, boolean getInstance, boolean getInheritance); + public List getClassTraits(Path className, boolean getStatic, boolean getInstance, boolean getInheritance); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java index 42e0832ec..ea3719c90 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/simpleparser/SimpleParser.java @@ -63,13 +63,60 @@ public interface SimpleParser { Map> externalTraitKeyToReference, Map separatorPosToType, Map separatorIsStatic, - Map> localTypeTraitNames, + Map> localTypeTraitNames, Map definitionToType, Map definitionToCallType, Integer caretPosition, - List variableSuggestions + List variableSuggestions ) throws SimpleParseException, IOException, InterruptedException; + + public static void fillSuggestionsOne( + List variableSuggestions, + Map varNameToDefinition, + Map positionToStatic, + Map definitionToType, + Map definitionToCallType, + Map definitionToSubType, + Map definitionToCallSubType, + Set used + ) { + for (Path p : varNameToDefinition.keySet()) { + int definition = varNameToDefinition.get(p); + if (definition >= 0) { + if (used.contains(p.getLast().toString())) { + continue; + } + used.add(p.getLast().toString()); + Path type = definitionToType.get(definition);; + Path callType = definitionToCallType.get(definition); + Variable subType = definitionToSubType.get(definition); + Variable callSubType = definitionToCallSubType.get(definition); + Boolean isStatic = positionToStatic.get(definition); + variableSuggestions.add(new Variable(true, p, definition, isStatic, type, callType, subType, callSubType)); + } + } + } + + public static void fillSuggestions(List variableSuggestions, + Map varNameToDefinition1, + Map varNameToDefinition2, + Map positionToStatic, + Map definitionToType, + Map definitionToCallType, + Map definitionToSubType, + Map definitionToCallSubType + ) { + Set used = new HashSet<>(); + if (varNameToDefinition1 != null) { + fillSuggestionsOne(variableSuggestions, varNameToDefinition1, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, used); + } + if (varNameToDefinition2 != null) { + fillSuggestionsOne(variableSuggestions, varNameToDefinition2, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, used); + } + variableSuggestions.add(new Variable(true, new Path("--finish--"), 0)); + } + public static void parseVariablesList( List sharedVariables, Map> definitionPosToReferences, @@ -84,11 +131,11 @@ public interface SimpleParser { Map> externalTraitKeyToReference, Map separatorPosToType, Map separatorIsStatic, - Map> localTypeTraitNames, + Map> localTypeTraits, Map definitionToType, Map definitionToCallType, Integer caretPosition, - List variableSuggestions + List variableSuggestions ) { List externalSimpleTypes = new ArrayList<>(); Map simpleExternalClassNameToFullClassName = new LinkedHashMap<>(); @@ -121,12 +168,17 @@ public interface SimpleParser { if (positionToStatic.containsKey(definition) && positionToStatic.get(definition)) { isStatic = true; } + Path traitType = definitionToType.get(definition); + Path traitCallType = definitionToCallType.get(definition); + Variable traitSubType = definitionToSubType.get(definition); + Variable traitCallSubType = definitionToCallSubType.get(definition); + Path cls = p.getParent(); String traitName = p.getLast().toString(); - if (!localTypeTraitNames.containsKey(cls)) { - localTypeTraitNames.put(cls, new ArrayList<>()); + if (!localTypeTraits.containsKey(cls)) { + localTypeTraits.put(cls, new ArrayList<>()); } - localTypeTraitNames.get(cls).add((isStatic ? "static::" : "") + traitName); + localTypeTraits.get(cls).add(new Variable(true, p.getLast(), definition, isStatic, traitType, traitCallType, traitSubType, traitCallSubType)); } parseVariablesList(variables, definitionPosToReferences, referenceToDefinition, parentVarFullNameToDefinitionPosition, parentVarNameToDefinitionPosition, positionToStatic, true, errors, null, innerFunctionCanUseTraits, externalSimpleTypes, externalTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, separatorIsStatic, caretPosition, variableSuggestions, null, null); @@ -139,21 +191,13 @@ public interface SimpleParser { if (caretPosition != null && variableSuggestions.isEmpty()) { if ((variables.isEmpty() || variables.get(variables.size() - 1).var.getPosition() <= caretPosition)) { - for (Path p : parentVarNameToDefinitionPosition.keySet()) { - if (parentVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - variableSuggestions.add("--finish--"); + fillSuggestions(variableSuggestions, parentVarNameToDefinitionPosition, null, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType); } } if (!variableSuggestions.isEmpty()) { variableSuggestions.remove(variableSuggestions.size() - 1); - } - Set uniqueSuggestions = new LinkedHashSet<>(variableSuggestions); - variableSuggestions.clear(); - variableSuggestions.addAll(uniqueSuggestions); + } } public static void parseVariablesList( @@ -182,7 +226,7 @@ public interface SimpleParser { Map separatorPosToType, Map separatorIsStatic, Integer caretPosition, - List variableSuggestions, + List variableSuggestions, Integer scopeStartPos, Integer scopeEndPos ) { @@ -203,17 +247,7 @@ public interface SimpleParser { && caretPosition >= scopeStartPos && vt.getPosition() > caretPosition && variableSuggestions.isEmpty()) { - for (Path p : parentVarNameToDefinitionPosition.keySet()) { - if (parentVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - for (Path p : privateVarNameToDefinitionPosition.keySet()) { - if (privateVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - variableSuggestions.add("--finish--"); + fillSuggestions(variableSuggestions, parentVarNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType); } if (vt instanceof Separator) { @@ -321,17 +355,7 @@ public interface SimpleParser { if (vt2 != null && caretPosition != null && variableSuggestions.isEmpty()) { if (vt.getPosition() <= caretPosition && vt2.getPosition() > caretPosition) { if (vt instanceof Variable) { - for (Path p : parentVarNameToDefinitionPosition.keySet()) { - if (parentVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - for (Path p : privateVarNameToDefinitionPosition.keySet()) { - if (privateVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - variableSuggestions.add("--finish--"); + fillSuggestions(variableSuggestions, parentVarNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType); } } } @@ -339,17 +363,7 @@ public interface SimpleParser { if (caretPosition != null && variableSuggestions.isEmpty() && scopeEndPos != null) { if (scopeEndPos > caretPosition) { - for (Path p : parentVarNameToDefinitionPosition.keySet()) { - if (parentVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - for (Path p : privateVarNameToDefinitionPosition.keySet()) { - if (privateVarNameToDefinitionPosition.get(p) >= 0) { - variableSuggestions.add(p.getFirst().toString()); - } - } - variableSuggestions.add("--finish--"); + fillSuggestions(variableSuggestions, parentVarNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType); } } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 817f72cae..655ae2cec 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -1144,8 +1144,39 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener getClassTraitNames(Path className, boolean getStatic, boolean getInstance, boolean getInheritance) { - return new ArrayList<>(abc.getSwf().getAbcIndex().getClassTraitNames(new TypeItem(className.toString()), abc, decompiledTextArea.getScriptIndex(), getStatic, getInstance, getInheritance)); + public List getClassTraits(Path className, boolean getStatic, boolean getInstance, boolean getInheritance) { + List propertyDefList = new ArrayList<>(); + List isStaticList = new ArrayList<>(); + abc.getSwf().getAbcIndex().getClassTraits(new TypeItem(className.toString()), abc, decompiledTextArea.getScriptIndex(), getStatic, getInstance, getInheritance, propertyDefList, isStaticList); + List ret = new ArrayList<>(); + for (int i = 0; i < propertyDefList.size(); i++) { + AbcIndexing.PropertyDef def = propertyDefList.get(i); + AbcIndexing.TraitIndex ti = abc.getSwf().getAbcIndex().findProperty(def, getStatic, getInstance, false, new Reference<>(null)); + Path type = null; + Path callType = null; + if (ti != null) { + type = typeToPath(ti.returnType); + callType = typeToPath(ti.callReturnType); + } + if (ti.trait instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) ti.trait; + if (tmgs.kindType == Trait.TRAIT_SETTER) { + int[] paramTypes = ti.abc.method_info.get(tmgs.method_info).param_types; + if (paramTypes.length == 1) { + type = new Path(ti.abc.constants.getMultiname(paramTypes[0]).getNameWithNamespace(ti.abc.constants, false).getStringParts()); + callType = null; + } else { + continue; + } + } + if (tmgs.kindType == Trait.TRAIT_GETTER) { + type = callType; + callType = null; + } + } + ret.add(new com.jpexs.decompiler.flash.simpleparser.Variable(true, new Path(def.getPropertyName()), 0, isStaticList.get(i), type, callType)); + } + return ret; } }); diff --git a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java index 28027163c..58e44e9fc 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/LineMarkedEditorPane.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.simpleparser.LinkHandler; import com.jpexs.decompiler.flash.simpleparser.LinkType; import com.jpexs.decompiler.flash.simpleparser.Path; import com.jpexs.decompiler.flash.simpleparser.SimpleParser; +import com.jpexs.decompiler.flash.simpleparser.Variable; import com.jpexs.helpers.Reference; import java.awt.Color; import java.awt.FontMetrics; @@ -114,7 +115,7 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan } @Override - public List getClassTraitNames(Path className, boolean getStatic, boolean getInstance, boolean getInheritance) { + public List getClassTraits(Path className, boolean getStatic, boolean getInstance, boolean getInheritance) { return new ArrayList<>(); } diff --git a/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java index 06a580932..4c0afd880 100644 --- a/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java +++ b/src/com/jpexs/decompiler/flash/gui/editor/VariableMarker.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.simpleparser.LinkType; import com.jpexs.decompiler.flash.simpleparser.Path; import com.jpexs.decompiler.flash.simpleparser.SimpleParseException; import com.jpexs.decompiler.flash.simpleparser.SimpleParser; +import com.jpexs.decompiler.flash.simpleparser.Variable; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -51,6 +52,7 @@ import java.beans.PropertyChangeListener; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -127,11 +129,11 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC private Map referenceToExternalTraitKey = new LinkedHashMap<>(); private Map> externalTraitKeyToReference = new LinkedHashMap<>(); private Map separatorPosToType = new LinkedHashMap<>(); - private Map> localTypeTraitNames = new LinkedHashMap<>(); + private Map> localTypeTraits = new LinkedHashMap<>(); private Map definitionToType = new LinkedHashMap<>(); private Map definitionToCallType = new LinkedHashMap<>(); private Map separatorIsStatic = new LinkedHashMap<>(); - private List variableSuggestions = new ArrayList<>(); + private List variableSuggestions = new ArrayList<>(); private MouseMotionAdapter mouseMotionAdapter; @@ -167,8 +169,8 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC private boolean goingOut = false; - private JList codeCompletionList; - private DefaultListModel codeCompletionListModel; + private JList codeCompletionList; + private DefaultListModel codeCompletionListModel; private JPopupMenu codeCompletionPopup; /** @@ -185,9 +187,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { - String selected = codeCompletionList.getSelectedValue(); + VariableListItem selected = codeCompletionList.getSelectedValue(); if (selected != null) { - completeCode(selected); + completeCode(selected.variable.name.getLast().toString()); } codeCompletionPopup.setVisible(false); } @@ -205,9 +207,9 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { - String selected = codeCompletionList.getSelectedValue(); + VariableListItem selected = codeCompletionList.getSelectedValue(); if (selected != null) { - completeCode(selected); + completeCode(selected.variable.name.getLast().toString()); } codeCompletionPopup.setVisible(false); if (selected == null) { @@ -565,7 +567,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC } boolean isDot = tokenAt != null && tokenAt.type == TokenType.OPERATOR ? ".".equals(sDoc.getText(tokenAt.start, tokenAt.length)) : false; - List suggestions = new ArrayList<>(); + List suggestions = new ArrayList<>(); if (isDot) { Token prevToken = sDoc.getPrevToken(tokenAt); @@ -585,30 +587,33 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC isStatic = true; } - if (localTypeTraitNames.containsKey(type)) { - for (String traitName : localTypeTraitNames.get(type)) { - if (isStatic && !traitName.startsWith("static::")) { + if (localTypeTraits.containsKey(type)) { + for (Variable traitName : localTypeTraits.get(type)) { + if (isStatic && !traitName.isStatic) { continue; } - if (traitName.startsWith("static::")) { - traitName = traitName.substring("static::".length()); + //remove constructor + if (traitName.name.toString().equals(type.getLast().toString())) { + continue; } - suggestions.add(traitName); - } - suggestions.remove(type.getLast().toString()); //remove constructor + suggestions.add(traitName); + } } else { //type = externalTypes.get(referenceToExternalTypeIndex.get(pos)); - List traitNames = ((LineMarkedEditorPane) pane).getLinkHandler().getClassTraitNames(type, true, true, true); - for (String traitName : traitNames) { - if (isStatic && !traitName.startsWith("static::")) { + if(simpleExternalClassNameToFullClassName.containsKey(type)) { + type = simpleExternalClassNameToFullClassName.get(type); + } + List traitNames = ((LineMarkedEditorPane) pane).getLinkHandler().getClassTraits(type, true, true, true); + for (Variable traitName : traitNames) { + if (isStatic && !traitName.isStatic) { continue; } - if (traitName.startsWith("static::")) { - traitName = traitName.substring("static::".length()); + //remove constructor + if (traitName.name.toString().equals(type.getLast().toString())) { + continue; } suggestions.add(traitName); } - suggestions.remove(type.getLast().toString()); //remove constructor } } } else { @@ -618,10 +623,16 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC codeCompletionPopup.setVisible(false); return; } - Collections.sort(suggestions, new NaturalOrderComparator()); + NaturalOrderComparator noc = new NaturalOrderComparator(); + Collections.sort(suggestions, new Comparator() { + @Override + public int compare(Variable o1, Variable o2) { + return noc.compare(o1.name.getLast().toString(), o2.name.getLast().toString()); + } + }); if (!identText.isEmpty()) { for (int i = suggestions.size() - 1; i >= 0; i--) { - String sug = suggestions.get(i); + String sug = suggestions.get(i).name.getLast().toString(); if (!sug.startsWith(identText)) { suggestions.remove(i); } @@ -632,15 +643,16 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC codeCompletionListModel.clear(); - for (String s : suggestions) { - codeCompletionListModel.addElement(s); + for (Variable s : suggestions) { + codeCompletionListModel.addElement(new VariableListItem(s)); } if (!codeCompletionPopup.isVisible() && !suggestions.isEmpty()) { Rectangle2D caretCoords = View.textComponentModelToView(pane, pane.getCaretPosition()); - codeCompletionPopup.show(pane, (int) caretCoords.getX(), (int) (caretCoords.getY() + caretCoords.getHeight())); - pane.requestFocusInWindow(); + codeCompletionPopup.show(pane, (int) caretCoords.getX(), (int) (caretCoords.getY() + caretCoords.getHeight())); } + pane.requestFocusInWindow(); + pane.getCaret().setVisible(true); } catch (BadLocationException ex) { //ignore } finally { @@ -999,11 +1011,11 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC Map newReferenceToExternalTraitKey = new LinkedHashMap<>(); Map> newExternalTraitKeyToReference = new LinkedHashMap<>(); Map newSeparatorPosToType = new LinkedHashMap<>(); - Map> newLocalTypeTraitNames = new LinkedHashMap<>(); + Map> newLocalTypeTraits = new LinkedHashMap<>(); Map newDefinitionToType = new LinkedHashMap<>(); Map newDefinitionToCallType = new LinkedHashMap<>(); Map newSeparatorIsStatic = new LinkedHashMap<>(); - List newVariableSuggestions = new ArrayList<>(); + List newVariableSuggestions = new ArrayList<>(); parser.parse( fullText, newDefinitionPosToReferences, @@ -1016,7 +1028,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC newReferenceToExternalTraitKey, newExternalTraitKeyToReference, newSeparatorPosToType, newSeparatorIsStatic, - newLocalTypeTraitNames, + newLocalTypeTraits, newDefinitionToType, newDefinitionToCallType, pos, @@ -1037,7 +1049,7 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC referenceToExternalTraitKey = newReferenceToExternalTraitKey; externalTraitKeyToReference = newExternalTraitKeyToReference; separatorPosToType = newSeparatorPosToType; - localTypeTraitNames = newLocalTypeTraitNames; + localTypeTraits = newLocalTypeTraits; definitionToType = newDefinitionToType; definitionToCallType = newDefinitionToCallType; separatorIsStatic = newSeparatorIsStatic; @@ -1266,4 +1278,29 @@ public class VariableMarker implements SyntaxComponent, CaretListener, PropertyC } } + private class VariableListItem { + private Variable variable; + + public VariableListItem(Variable variable) { + this.variable = variable; + } + + public Variable getVariable() { + return variable; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(variable.name.getLast().toString()); + if (variable.callType != null) { + sb.append("() : "); + sb.append(variable.callType.getLast().toString()); + } else if (variable.type != null) { + sb.append(" : "); + sb.append(variable.type.getLast().toString()); + } + return sb.toString(); + } + } }