Skip to content

Commit

Permalink
CompletionProvider: completion for :: namespaces access (closes #782)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshtynjala committed Nov 1, 2024
1 parent e33c594 commit 7dd1ef4
Showing 1 changed file with 61 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
import org.apache.royale.compiler.tree.as.IModifierNode;
import org.apache.royale.compiler.tree.as.INamespaceAccessExpressionNode;
import org.apache.royale.compiler.tree.as.INamespaceDecorationNode;
import org.apache.royale.compiler.tree.as.IOperatorNode.OperatorType;
import org.apache.royale.compiler.tree.as.IPackageNode;
import org.apache.royale.compiler.tree.as.IScopedNode;
Expand Down Expand Up @@ -670,8 +671,8 @@ private CompletionList actionScriptCompletion(IASNode offsetNode, Path path, Pos
if ((line != leftOperand.getEndLine() && line != rightOperand.getLine())
|| (line == leftOperand.getEndLine() && column > leftOperand.getEndColumn())
|| (line == rightOperand.getLine() && column <= rightOperand.getColumn())) {
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData, project,
result);
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData,
project, result);
return result;
}
}
Expand All @@ -689,8 +690,8 @@ private CompletionList actionScriptCompletion(IASNode offsetNode, Path path, Pos
isValidLeft = false;
}
if (offsetNode == memberAccessNode.getRightOperandNode() || isValidLeft) {
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData, project,
result);
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData,
project, result);
return result;
}
}
Expand All @@ -703,17 +704,26 @@ private CompletionList actionScriptCompletion(IASNode offsetNode, Path path, Pos
if (rightOperandNode instanceof IIdentifierNode) {
IIdentifierNode identifierNode = (IIdentifierNode) rightOperandNode;
if (identifierNode.getName().equals("")) {
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData, project,
result);
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction, addImportData,
project, result);
return result;
}
}
}

// namespace access
if (parentNode != null && parentNode instanceof INamespaceAccessExpressionNode) {
INamespaceAccessExpressionNode namespaceAccessNode = (INamespaceAccessExpressionNode) parentNode;
IASNode gpNode = parentNode.getParent();
if (gpNode != null && gpNode instanceof IMemberAccessExpressionNode) {
IMemberAccessExpressionNode memberAccessNode = (IMemberAccessExpressionNode) gpNode;
if (namespaceAccessNode == memberAccessNode.getRightOperandNode()) {
autoCompleteMemberAccess(memberAccessNode, nextChar, isParamOfTypeFunction,
addImportData, project, result);
return result;
}
}
// we don't want this falling into scope completion
// TODO: ideally, we'd complete namespaces and members in them
return result;
}

Expand Down Expand Up @@ -769,7 +779,8 @@ private CompletionList actionScriptCompletion(IASNode offsetNode, Path path, Pos
IScopedNode scopedNode = (IScopedNode) currentNodeForScope;

// include all members and local things that are in scope
autoCompleteScope(scopedNode, false, nextChar, isParamOfTypeFunction, addImportData, project, result);
autoCompleteScope(scopedNode, false, nextChar, isParamOfTypeFunction, addImportData,
project, result);

// include all public definitions
IASScope scope = scopedNode.getScope();
Expand Down Expand Up @@ -1286,8 +1297,9 @@ private void autoCompleteTypes(IASNode withNode, IDefinition priorityNewClass, A
priorityNewClass, false, addImportData);
}

private void autoCompleteScope(IScopedNode scopedNode, boolean typesOnly, char nextChar,
boolean isParamOfTypeFunction, AddImportData addImportData, ILspProject project, CompletionList result) {
private void autoCompleteScope(IScopedNode scopedNode, boolean typesOnly,
char nextChar, boolean isParamOfTypeFunction, AddImportData addImportData, ILspProject project,
CompletionList result) {
IScopedNode currentNode = scopedNode;
ASScope scope = (ASScope) scopedNode.getScope();
while (currentNode != null) {
Expand All @@ -1296,12 +1308,12 @@ private void autoCompleteScope(IScopedNode scopedNode, boolean typesOnly, char n
boolean staticOnly = currentNode == scopedNode && isType;
if (currentScope instanceof TypeScope && !typesOnly) {
TypeScope typeScope = (TypeScope) currentScope;
addDefinitionsInTypeScopeToAutoComplete(typeScope, scope, scopedNode, true, true, false, false, null,
false, false, nextChar, null, isParamOfTypeFunction, addImportData, null, null, project,
result);
addDefinitionsInTypeScopeToAutoComplete(typeScope, scope, null, scopedNode, true, true, false,
false, null, false, false, nextChar, null, isParamOfTypeFunction, addImportData, null, null,
project, result);
if (!staticOnly) {
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, scopedNode, false, nextChar,
null, isParamOfTypeFunction, addImportData, project, result);
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, null, scopedNode,
false, nextChar, null, isParamOfTypeFunction, addImportData, project, result);
}
} else {
Collection<IDefinition> localDefs = new ArrayList<>(currentScope.getAllLocalDefinitions());
Expand Down Expand Up @@ -1494,16 +1506,32 @@ private void autoCompleteFunctionOverrides(IASNode node, AddImportData addImport
}
}

private void autoCompleteMemberAccess(IMemberAccessExpressionNode node, char nextChar,
private void autoCompleteMemberAccess(IMemberAccessExpressionNode node,
char nextChar,
boolean isParamOfTypeFunction, AddImportData addImportData,
ILspProject project, CompletionList result) {
ASScope scope = (ASScope) node.getContainingScope().getScope();
IExpressionNode leftOperand = node.getLeftOperandNode();
IExpressionNode rightOperand = node.getRightOperandNode();
Set<INamespaceDefinition> namespaceSet = null;
if (rightOperand instanceof INamespaceAccessExpressionNode) {
INamespaceAccessExpressionNode nsNode = (INamespaceAccessExpressionNode) rightOperand;
IExpressionNode leftNsOperand = nsNode.getLeftOperandNode();
if (leftNsOperand instanceof INamespaceDecorationNode) {
IDefinition resolved = leftNsOperand.resolve(project);
if (resolved != null && resolved instanceof INamespaceDefinition) {
INamespaceDefinition nsDefinition = (INamespaceDefinition) resolved;
namespaceSet = new HashSet<>();
namespaceSet.add(nsDefinition);
}
}
}
IDefinition leftDefinition = leftOperand.resolve(project);
if (leftDefinition != null && leftDefinition instanceof ITypeDefinition) {
ITypeDefinition typeDefinition = (ITypeDefinition) leftDefinition;
TypeScope typeScope = (TypeScope) typeDefinition.getContainedScope();
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, node, true, nextChar, null,
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, namespaceSet, node, true, nextChar,
null,
isParamOfTypeFunction, addImportData, project, result);
return;
}
Expand All @@ -1517,7 +1545,8 @@ private void autoCompleteMemberAccess(IMemberAccessExpressionNode node, char nex
ITypeDefinition elementType = vectorDef.resolveElementType(project);
if (elementType != null) {
TypeScope typeScope = (TypeScope) elementType.getContainedScope();
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, node, false, nextChar,
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, namespaceSet, node, false,
nextChar,
null, isParamOfTypeFunction, addImportData, project, result);
return;
}
Expand All @@ -1540,7 +1569,7 @@ private void autoCompleteMemberAccess(IMemberAccessExpressionNode node, char nex
}
}

addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, node, false, nextChar,
addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, namespaceSet, node, false, nextChar,
prioritySuperFunction, isParamOfTypeFunction, addImportData, project, result);
return;
}
Expand Down Expand Up @@ -1812,23 +1841,28 @@ private void addLanguageAttributesToAutoCompleteMXML(TypeScope typeScope, ASScop
}

private void addDefinitionsInTypeScopeToAutoCompleteActionScript(TypeScope typeScope, ASScope otherScope,
IASNode offsetNode, boolean isStatic, char nextChar, IFunctionNode prioritySuperFunction,
Set<INamespaceDefinition> namespaceSet, IASNode offsetNode, boolean isStatic, char nextChar,
IFunctionNode prioritySuperFunction,
boolean isParamOfTypeFunction, AddImportData addImportData, ILspProject project, CompletionList result) {
addDefinitionsInTypeScopeToAutoComplete(typeScope, otherScope, offsetNode, isStatic, false, false, false, null,
addDefinitionsInTypeScopeToAutoComplete(typeScope, otherScope, namespaceSet, offsetNode, isStatic, false, false,
false, null,
false, false, nextChar, prioritySuperFunction, isParamOfTypeFunction, addImportData, null, null,
project, result);
}

private void addDefinitionsInTypeScopeToAutoCompleteMXML(TypeScope typeScope, ASScope otherScope,
boolean isAttribute, String prefix, boolean includeOpenTagBracket, boolean includeOpenTagPrefix,
boolean isAttribute, String prefix, boolean includeOpenTagBracket,
boolean includeOpenTagPrefix,
AddImportData addImportData, Position xmlnsPosition, IMXMLTagData offsetTag,
ILspProject project, CompletionList result) {
addDefinitionsInTypeScopeToAutoComplete(typeScope, otherScope, null, false, false, true, isAttribute,
addDefinitionsInTypeScopeToAutoComplete(typeScope, otherScope, null, null, false, false, true,
isAttribute,
prefix, includeOpenTagBracket, includeOpenTagPrefix, (char) -1, null, false, addImportData,
xmlnsPosition, offsetTag, project, result);
}

private void addDefinitionsInTypeScopeToAutoComplete(TypeScope typeScope, ASScope otherScope, IASNode offsetNode,
private void addDefinitionsInTypeScopeToAutoComplete(TypeScope typeScope, ASScope otherScope,
Set<INamespaceDefinition> namespaceSet, IASNode offsetNode,
boolean isStatic, boolean includeSuperStatics, boolean forMXML, boolean isAttribute,
String prefix, boolean includeOpenTagBracket, boolean includeOpenTagPrefix, char nextChar,
IFunctionNode prioritySuperFunction, boolean isParamOfTypeFunction, AddImportData addImportData,
Expand All @@ -1847,7 +1881,9 @@ private void addDefinitionsInTypeScopeToAutoComplete(TypeScope typeScope, ASScop
excludeMetaTags.addAll(Arrays.asList(currentTags));
}
ArrayList<IDefinition> memberAccessDefinitions = new ArrayList<>();
Set<INamespaceDefinition> namespaceSet = ScopeUtils.getNamespaceSetForScopes(typeScope, otherScope, project);
if (namespaceSet == null) {
namespaceSet = ScopeUtils.getNamespaceSetForScopes(typeScope, otherScope, project);
}

boolean isInterfaceScope = typeScope.getDefinition() instanceof IInterfaceDefinition;
typeScope.getAllPropertiesForMemberAccess((CompilerProject) project, memberAccessDefinitions, namespaceSet);
Expand Down

0 comments on commit 7dd1ef4

Please sign in to comment.