Added: AS3 - code completion (properties and methods)

This commit is contained in:
Jindra Petřík
2025-06-14 20:59:38 +02:00
parent 209f8ca593
commit 24e34ca272
12 changed files with 539 additions and 43 deletions

View File

@@ -38,6 +38,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.helpers.Reference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -566,7 +567,7 @@ public final class AbcIndexing {
private Map<DottedChain, Set<String>> pkgToObjectsName = new LinkedHashMap<>();
private final Map<ClassDef, ClassIndex> classes = new HashMap<>();
private final Map<PropertyDef, TraitIndex> instanceProperties = new HashMap<>();
private final Map<PropertyDef, TraitIndex> classProperties = new HashMap<>();
@@ -614,6 +615,65 @@ public final class AbcIndexing {
}
return classNames;
}
public Set<String> getClassTraitNames(GraphTargetItem cls, ABC abc, Integer scriptIndex, boolean getStatic, boolean getInstance, boolean getInheritance) {
ClassIndex ci = findClass(cls, abc, scriptIndex);
if (ci == null) {
return new LinkedHashSet<>();
}
Set<String> ret = new LinkedHashSet<>();
getClassIndexTraitNames(ret, ci, getStatic, getInstance, getInheritance);
return ret;
}
private void getClassIndexTraitNames(Set<String> ret, ClassIndex ci, boolean getStatic, boolean getInstance, boolean getInheritance) {
GraphTargetItem ciName = multinameToType(ci.abc.instance_info.get(ci.index).name_index, ci.abc.constants);
boolean isObject = ciName.equals(new TypeItem("Object"));
List<String> ignoredObjectTraits = Arrays.asList("_init", "_dontEnumPrototype", "_setPropertyIsEnumerable");
if (getInstance) {
for (PropertyDef def : instanceProperties.keySet()) {
if (isObject && ignoredObjectTraits.contains(def.propName)) {
continue;
}
int nsKind = -1;
if (def.propNsIndex != 0) {
nsKind = def.abc.constants.getNamespace(def.propNsIndex).kind;
}
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 (getStatic) {
for (PropertyDef def : classProperties.keySet()) {
if (isObject && ignoredObjectTraits.contains(def.propName)) {
continue;
}
int nsKind = -1;
if (def.propNsIndex != 0) {
nsKind = def.abc.constants.getNamespace(def.propNsIndex).kind;
}
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 (getInheritance && ci.parent != null) {
getClassIndexTraitNames(ret, ci.parent, getStatic, getInstance, getInheritance);
}
if (parent != null) {
parent.getClassIndexTraitNames(ret, ci, getStatic, getInstance, getInheritance);
}
}
/**
* Finds class in index.

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.simpleparser.LinkHandler;
import com.jpexs.decompiler.flash.simpleparser.MethodScope;
import com.jpexs.decompiler.flash.simpleparser.Namespace;
import com.jpexs.decompiler.flash.simpleparser.Path;
import com.jpexs.decompiler.flash.simpleparser.Separator;
import com.jpexs.decompiler.flash.simpleparser.SimpleParseException;
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
import com.jpexs.decompiler.flash.simpleparser.TraitVarConstValueScope;
@@ -46,6 +47,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
/**
@@ -168,8 +170,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
ret = true;
break;
case PARENT_OPEN:
call(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
lastVarName = lastVarName.add(Path.PATH_PARENTHESIS);
lastVarName = call(lastVarName, errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
ret = true;
break;
case DESCENDANTS:
@@ -246,8 +247,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
while (s.isType(SymbolType.DOT, SymbolType.NULL_DOT, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME)) {
ParsedSymbol s2 = lex();
if (s.type == SymbolType.NULL_DOT) {
variables.add(new Separator(lastVarName, s.position));
lexer.pushback(s2);
} else if (s.type == SymbolType.DOT) {
variables.add(new Separator(lastVarName, s.position));
if (s2.type == SymbolType.ATTRIBUTE) {
//attribute
} else {
@@ -264,7 +267,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
} else if (s.type == SymbolType.BRACKET_OPEN) {
lastVarName = lastVarName.add(Path.PATH_BRACKETS);
expression(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, true, variables, false, abc);
expectedType(errors, SymbolType.BRACKET_CLOSE);
s = lex();
if (expected(errors, s, lexer.yyline(), SymbolType.BRACKET_CLOSE)) {
variables.add(new Separator(lastVarName, s.position));
}
ret = true;
s = lex();
} else {
@@ -331,6 +337,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
while (s.isType(SymbolType.DOT)) {
variables.add(new Variable(false, fullName, identPos));
variables.add(new Separator(fullName, s.position));
s = lex();
lastName = "";
if (s.type == SymbolType.ATTRIBUTE) {
@@ -351,6 +358,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
} else {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY)) {
lexer.pushback(s);
return new Path();
}
lastName = s.value.toString();
@@ -434,7 +442,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
return ret;
}
private void call(List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private Path call(Path lastVarName, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
//expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER
ParsedSymbol s = lex();
while (s.type != SymbolType.PARENT_CLOSE) {
@@ -447,6 +455,12 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
}
}
if (s.type == SymbolType.PARENT_CLOSE) {
lastVarName = lastVarName.add(Path.PATH_PARENTHESIS);
variables.add(new Separator(lastVarName, s.position));
}
return lastVarName;
}
private void method(List<SimpleParseException> errors, boolean outsidePackage, boolean isPrivate, boolean isInterface, boolean isNative, String customAccess, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, boolean override, boolean isFinal, TypeItem thisType, List<NamespaceItem> openedNamespaces, boolean isStatic, Path functionName, boolean isMethod, List<VariableOrScope> variables, ABC abc, int methodNamePos, Reference<Path> returnTypeRef, Reference<Variable> returnSubTypeRef) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
@@ -1369,7 +1383,8 @@ public class ActionScript3SimpleParser implements SimpleParser {
case SUPER: //constructor call
ParsedSymbol ss2 = lex();
if (ss2.type == SymbolType.PARENT_OPEN) {
call(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
Path lastVarName = new Path("super");
lastVarName = call(lastVarName, errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
ret = true;
} else { //no constructor call, but it could be calling parent methods... => handle in expression
lexer.pushback(ss2);
@@ -2062,7 +2077,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
applyType(errors, thisType, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, isStatic, variables, abc);
expectedType(errors, SymbolType.PARENT_CLOSE);
expectedType(errors, SymbolType.PARENT_OPEN);
call(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
lastVarName = call(lastVarName, errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
ret = true;
} else {
@@ -2071,7 +2086,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
name(errors, thisType, needsActivation, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, importedClasses, abc);
applyType(errors, thisType, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, isStatic, variables, abc);
expectedType(errors, SymbolType.PARENT_OPEN);
call(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
lastVarName = call(lastVarName, errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
ret = true;
}
allowMemberOrCall = true;
@@ -2280,7 +2295,11 @@ public class ActionScript3SimpleParser implements SimpleParser {
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
Map<Path, List<Integer>> externalTraitKeyToReference,
Map<Integer, Path> separatorPosToType,
Map<Path, List<String>> localTypeTraitNames,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType
) throws SimpleParseException, IOException, InterruptedException {
List<List<NamespaceItem>> allOpenedNamespaces = new ArrayList<>();
Reference<Boolean> sinitNeedsActivation = new Reference<>(false);
@@ -2300,7 +2319,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
//Logger.getLogger(ActionScript3SimpleParser.class.getName()).log(Level.SEVERE, null, ex);
throw new SimpleParseException(str, ex.line);
}
SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, true, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference);
SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, true, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, localTypeTraitNames, definitionToType, definitionToCallType);
}
/**

View File

@@ -40,6 +40,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* ActionScript 1/2 parser.
@@ -1579,7 +1580,11 @@ public class ActionScript2SimpleParser implements SimpleParser {
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
Map<Path, List<Integer>> externalTraitKeyToReference,
Map<Integer, Path> separatorPosToType,
Map<Path, List<String>> localTypeTraitNames,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType
) throws SimpleParseException, IOException, InterruptedException {
List<VariableOrScope> vars = new ArrayList<>();
@@ -1670,7 +1675,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
} catch (ActionParseException ex) {
errors.add(new SimpleParseException(ex.getMessage(), ex.line, ex.position));
}
SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, false, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference);
SimpleParser.parseVariablesList(new ArrayList<>(), vars, definitionPosToReferences, referenceToDefinition, errors, false, externalTypes, referenceToExternalTypeIndex, externalTypeIndexToReference, linkHandler, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType, localTypeTraitNames, definitionToType, definitionToCallType);
}
private void versionRequired(List<SimpleParseException> errors, ParsedSymbol s, int min) throws SimpleParseException {

View File

@@ -16,6 +16,8 @@
*/
package com.jpexs.decompiler.flash.simpleparser;
import java.util.List;
/**
* Handler of links.
* @author JPEXS
@@ -37,5 +39,6 @@ public interface LinkHandler {
public void handleClassLink(Path className);
public void handleTraitLink(Path className, String traitName);
public List<String> getClassTraitNames(Path className, boolean getStatic, boolean getInstance, boolean getInheritance);
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2010-2025 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.simpleparser;
/**
*
* @author JPEXS
*/
public class Separator implements VariableOrScope {
public Path parentName;
public int position;
public Separator(Path parentName, int position) {
this.parentName = parentName;
this.position = position;
}
}

View File

@@ -26,6 +26,7 @@ import java.util.Set;
/**
* Simple parser used for highlighting in editors.
*
* @author JPEXS
*/
public interface SimpleParser {
@@ -57,7 +58,11 @@ public interface SimpleParser {
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
Map<Path, List<Integer>> externalTraitKeyToReference,
Map<Integer, Path> separatorPosToType,
Map<Path, List<String>> localTypeTraitNames,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType
) throws SimpleParseException, IOException, InterruptedException;
public static void parseVariablesList(
@@ -72,17 +77,21 @@ public interface SimpleParser {
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
Map<Path, List<Integer>> externalTraitKeyToReference,
Map<Integer, Path> separatorPosToType,
Map<Path, List<String>> localTypeTraitNames,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType
) {
List<Path> externalSimpleTypes = new ArrayList<>();
Map<Path, Path> simpleExternalClassNameToFullClassName = new LinkedHashMap<>();
for (Path type : externalTypes) {
externalSimpleTypes.add(type.getLast());
simpleExternalClassNameToFullClassName.put(type.getLast(), type);
simpleExternalClassNameToFullClassName.put(type.getLast(), type);
}
Map<Integer, Path> definitionToType = new LinkedHashMap<>();
Map<Integer, Path> definitionToCallType = new LinkedHashMap<>();
//Map<Integer, Path> definitionToType = new LinkedHashMap<>();
//Map<Integer, Path> definitionToCallType = new LinkedHashMap<>();
Map<Integer, Variable> definitionToSubType = new LinkedHashMap<>();
Map<Integer, Variable> definitionToCallSubType = new LinkedHashMap<>();
Map<Path, Integer> traitFullNameToDefinition = new LinkedHashMap<>();
@@ -91,7 +100,16 @@ public interface SimpleParser {
findClassTraits(privateVariables, traitFullNameToDefinition, definitionPosToReferences, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType);
findClassTraits(sharedVariables, traitFullNameToDefinition, definitionPosToReferences, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType);
parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), positionToStatic, true, errors, null, innerFunctionCanUseTraits, externalSimpleTypes, externalTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
for (Path p : traitFullNameToDefinition.keySet()) {
Path cls = p.getParent();
String traitName = p.getLast().toString();
if (!localTypeTraitNames.containsKey(cls)) {
localTypeTraitNames.put(cls, new ArrayList<>());
}
localTypeTraitNames.get(cls).add(traitName);
}
parseVariablesList(privateVariables, sharedVariables, definitionPosToReferences, referenceToDefinition, new LinkedHashMap<>(), new LinkedHashMap<>(), positionToStatic, true, errors, null, innerFunctionCanUseTraits, externalSimpleTypes, externalTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType);
for (Map.Entry<Integer, Integer> entry : referenceToExternalTypeIndex.entrySet()) {
if (!externalTypeIndexToReference.containsKey(entry.getValue())) {
externalTypeIndexToReference.put(entry.getValue(), new ArrayList<>());
@@ -123,7 +141,8 @@ public interface SimpleParser {
LinkHandler linkHandler,
Map<Path, Path> simpleExternalClassNameToFullClassName,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
Map<Path, List<Integer>> externalTraitKeyToReference,
Map<Integer, Path> separatorPosToType
) {
Map<Path, Integer> privateVarNameToDefinitionPosition = new LinkedHashMap<>();
privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition);
@@ -132,6 +151,10 @@ public interface SimpleParser {
privateVarFullNameToDefinitionPosition.putAll(parentVarFullNameToDefinitionPosition);
for (VariableOrScope vt : privateVariables) {
if (vt instanceof Separator) {
Separator s = (Separator) vt;
searchTrait(s.parentName, s.position, true, separatorPosToType, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
}
if (vt instanceof Variable) {
Variable v = (Variable) vt;
if (v.definition) {
@@ -156,7 +179,7 @@ public interface SimpleParser {
} else if (externalSimpleTypes.contains(v.name)) {
referenceToExternalTypeIndex.put(v.position, externalSimpleTypes.indexOf(v.name));
} else {
boolean traitFound = searchTrait(v, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
boolean traitFound = searchTrait(v.name, v.position, false, separatorPosToType, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
if (!traitFound) {
parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
parentVarNameToDefinitionPosition.put(v.getLastName(), -v.position - 1);
@@ -219,10 +242,14 @@ public interface SimpleParser {
}
}
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, subPrivateVarFullNameToDefinitionPosition, subPrivateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, externalFullTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, subPrivateVarFullNameToDefinitionPosition, subPrivateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, externalFullTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType);
}
}
for (VariableOrScope vt : sharedVariables) {
if (vt instanceof Separator) {
Separator s = (Separator) vt;
searchTrait(s.parentName, s.position, true, separatorPosToType, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
}
if (vt instanceof Variable) {
Variable v = (Variable) vt;
if (v.definition) {
@@ -249,7 +276,7 @@ public interface SimpleParser {
} else if (externalSimpleTypes.contains(v.name)) {
referenceToExternalTypeIndex.put(v.position, externalSimpleTypes.indexOf(v.name));
} else {
boolean traitFound = searchTrait(v, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
boolean traitFound = searchTrait(v.name, v.position, false, separatorPosToType, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, definitionPosToReferences, referenceToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
if (!traitFound) {
parentVarFullNameToDefinitionPosition.put(v.name, -v.position - 1);
parentVarNameToDefinitionPosition.put(v.getFirstName(), -v.position - 1);
@@ -305,14 +332,14 @@ public interface SimpleParser {
if (vName.toString().equals("this")) {
subPrivateVarNameToDefinitionPosition.remove(new Path("this"));
}
if (!innerFunctionCanUseTraits) {
if (!innerFunctionCanUseTraits) {
subPrivateVarNameToDefinitionPosition.remove(vName.getLast());
}
}
}
}
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, externalFullTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference);
parseVariablesList(vs.getPrivateItems(), vs.getSharedItems(), definitionPosToReferences, referenceToDefinition, privateVarFullNameToDefinitionPosition, privateVarNameToDefinitionPosition, positionToStatic, subStatic, errors, vs, innerFunctionCanUseTraits, externalSimpleTypes, externalFullTypes, referenceToExternalTypeIndex, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType, traitFullNameToDefinition, linkHandler, simpleExternalClassNameToFullClassName, referenceToExternalTraitKey, externalTraitKeyToReference, separatorPosToType);
}
}
}
@@ -355,7 +382,10 @@ public interface SimpleParser {
}
public static boolean searchTrait(
Variable v,
Path vName,
int vPosition,
boolean separator,
Map<Integer, Path> separatorPosToType,
Map<Path, Integer> privateVarFullNameToDefinitionPosition,
Map<Path, Integer> privateVarNameToDefinitionPosition,
Map<Integer, Path> definitionToType,
@@ -371,12 +401,12 @@ public interface SimpleParser {
Map<Path, List<Integer>> externalTraitKeyToReference
) {
boolean traitFound = false;
if (v.hasParent()) {
if (vName.hasParent()) {
//List<String> parts = v.getParts();
Path parts = v.name;
Path parts = vName;
Integer definitionPos = null;
Path firstName = v.getFirstName();
Path firstName = vName.getFirst();
if (privateVarFullNameToDefinitionPosition.containsKey(firstName)) {
definitionPos = privateVarFullNameToDefinitionPosition.get(firstName);
} else if (privateVarNameToDefinitionPosition.containsKey(firstName)) {
@@ -427,12 +457,12 @@ public interface SimpleParser {
break;
}
type = lastSubType.name;
} else {
} else {
if (externalSubTypes.isEmpty()) {
traitFound = false;
break;
}
type = externalSubTypes.remove(0);
type = externalSubTypes.remove(0);
}
} else {
if (type == null) {
@@ -444,9 +474,9 @@ public interface SimpleParser {
type = simpleExternalClassNameToFullClassName.get(type);
}
traitKey = type.add(part);
Path newType = linkHandler.getTraitType(type, part.toString());
Path newType = linkHandler.getTraitType(type, part.toString());
if (newType == null) {
traitFound = false;
traitFound = false;
break;
}
externalSubTypes.clear();
@@ -477,7 +507,7 @@ public interface SimpleParser {
}
externalCallSubTypes.clear();
externalSubTypes.clear();
externalCallType = null;
externalCallType = null;
definitionPos = traitFullNameToDefinition.get(traitKey);
type = definitionToType.get(definitionPos);
lastSubType = null;
@@ -486,16 +516,49 @@ public interface SimpleParser {
if (traitFound) {
if (definitionPos != null) {
definitionPosToReferences.get(definitionPos).add(v.position);
referenceToDefinition.put(v.position, definitionPos);
definitionPosToReferences.get(definitionPos).add(vPosition);
referenceToDefinition.put(vPosition, definitionPos);
} else if (part != null) {
if (!externalTraitKeyToReference.containsKey(traitKey)) {
externalTraitKeyToReference.put(traitKey, new ArrayList<>());
}
externalTraitKeyToReference.get(traitKey).add(v.position);
referenceToExternalTraitKey.put(v.position, traitKey);
externalTraitKeyToReference.get(traitKey).add(vPosition);
referenceToExternalTraitKey.put(vPosition, traitKey);
}
}
if (separator) {
separatorPosToType.put(vPosition, type);
}
}
}
} else if (separator) {
Integer definitionPos = null;
Path firstName = vName.getFirst();
if (privateVarFullNameToDefinitionPosition.containsKey(firstName)) {
definitionPos = privateVarFullNameToDefinitionPosition.get(firstName);
} else if (privateVarNameToDefinitionPosition.containsKey(firstName)) {
definitionPos = privateVarNameToDefinitionPosition.get(firstName);
}
Path type = null;
if (definitionPos != null) {
if (definitionToType.containsKey(definitionPos)) {
type = definitionToType.get(definitionPos);
}
} else if (simpleExternalClassNameToFullClassName.containsKey(firstName)) {
type = simpleExternalClassNameToFullClassName.get(firstName);
}
if (type != null) {
if (definitionPos != null) {
definitionPosToReferences.get(definitionPos).add(vPosition);
referenceToDefinition.put(vPosition, definitionPos);
}
/* else {
if (!externalTraitKeyToReference.containsKey(traitKey)) {
externalTraitKeyToReference.put(traitKey, new ArrayList<>());
}
externalTraitKeyToReference.get(traitKey).add(vPosition);
referenceToExternalTraitKey.put(vPosition, traitKey);
}*/
separatorPosToType.put(vPosition, type);
}
}
return traitFound;