Search in sources :

Example 1 with IASScope

use of org.apache.flex.compiler.scopes.IASScope in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method mxmlReferences.

private CompletableFuture<List<? extends Location>> mxmlReferences(ReferenceParams params, IMXMLTagData offsetTag) {
    IDefinition definition = getDefinitionForMXMLNameAtOffset(offsetTag, currentOffset);
    if (definition != null) {
        if (isInsideTagPrefix(offsetTag, currentOffset)) {
            //ignore the tag's prefix
            return CompletableFuture.completedFuture(Collections.emptyList());
        }
        ArrayList<Location> result = new ArrayList<>();
        referencesForDefinition(definition, result);
        return CompletableFuture.completedFuture(result);
    }
    //finally, check if we're looking for references to a tag's id
    IMXMLTagAttributeData attributeData = getMXMLTagAttributeWithValueAtOffset(offsetTag, currentOffset);
    if (attributeData == null || !attributeData.getName().equals(IMXMLLanguageConstants.ATTRIBUTE_ID)) {
        //definition referenced at the current position.
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    Path path = LanguageServerUtils.getPathFromLanguageServerURI(params.getTextDocument().getUri());
    if (path == null) {
        //this probably shouldn't happen, but check just to be safe
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    ICompilationUnit unit = getCompilationUnit(path);
    Collection<IDefinition> definitions = null;
    try {
        definitions = unit.getFileScopeRequest().get().getExternallyVisibleDefinitions();
    } catch (Exception e) {
    //safe to ignore
    }
    if (definitions == null || definitions.size() == 0) {
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    IClassDefinition classDefinition = null;
    for (IDefinition currentDefinition : definitions) {
        if (currentDefinition instanceof IClassDefinition) {
            classDefinition = (IClassDefinition) currentDefinition;
            break;
        }
    }
    if (classDefinition == null) {
        //this probably shouldn't happen, but check just to be safe
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    IASScope scope = classDefinition.getContainedScope();
    for (IDefinition currentDefinition : scope.getAllLocalDefinitions()) {
        if (currentDefinition.getBaseName().equals(attributeData.getRawValue())) {
            definition = currentDefinition;
            break;
        }
    }
    if (definition == null) {
        //definition referenced at the current position.
        return CompletableFuture.completedFuture(Collections.emptyList());
    }
    ArrayList<Location> result = new ArrayList<>();
    referencesForDefinition(definition, result);
    return CompletableFuture.completedFuture(result);
}
Also used : Path(java.nio.file.Path) ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) IASScope(org.apache.flex.compiler.scopes.IASScope) ArrayList(java.util.ArrayList) IDefinition(org.apache.flex.compiler.definitions.IDefinition) ConcurrentModificationException(java.util.ConcurrentModificationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) Location(org.eclipse.lsp4j.Location) ISourceLocation(org.apache.flex.compiler.common.ISourceLocation) IMXMLTagAttributeData(org.apache.flex.compiler.mxml.IMXMLTagAttributeData)

Example 2 with IASScope

use of org.apache.flex.compiler.scopes.IASScope in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method querySymbolsInScope.

private void querySymbolsInScope(String query, IASScope scope, List<SymbolInformation> result) {
    String lowerCaseQuery = query.toLowerCase();
    Collection<IDefinition> definitions = scope.getAllLocalDefinitions();
    for (IDefinition definition : definitions) {
        if (definition instanceof IPackageDefinition) {
            IPackageDefinition packageDefinition = (IPackageDefinition) definition;
            IASScope packageScope = packageDefinition.getContainedScope();
            querySymbolsInScope(query, packageScope, result);
        } else if (definition instanceof ITypeDefinition) {
            ITypeDefinition typeDefinition = (ITypeDefinition) definition;
            if (!definition.isImplicit() && typeDefinition.getQualifiedName().toLowerCase().contains(lowerCaseQuery)) {
                SymbolInformation symbol = definitionToSymbol(typeDefinition);
                result.add(symbol);
            }
            IASScope typeScope = typeDefinition.getContainedScope();
            querySymbolsInScope(query, typeScope, result);
        } else if (definition instanceof IFunctionDefinition) {
            if (definition.isImplicit()) {
                continue;
            }
            IFunctionDefinition functionDefinition = (IFunctionDefinition) definition;
            if (functionDefinition.getQualifiedName().toLowerCase().contains(lowerCaseQuery)) {
                SymbolInformation symbol = definitionToSymbol(functionDefinition);
                result.add(symbol);
            }
            IASScope functionScope = functionDefinition.getContainedScope();
            querySymbolsInScope(query, functionScope, result);
        } else if (definition instanceof IVariableDefinition) {
            if (definition.isImplicit()) {
                continue;
            }
            IVariableDefinition variableDefinition = (IVariableDefinition) definition;
            if (variableDefinition.getQualifiedName().toLowerCase().contains(lowerCaseQuery)) {
                SymbolInformation symbol = definitionToSymbol(variableDefinition);
                result.add(symbol);
            }
        }
    }
}
Also used : IFunctionDefinition(org.apache.flex.compiler.definitions.IFunctionDefinition) IASScope(org.apache.flex.compiler.scopes.IASScope) IPackageDefinition(org.apache.flex.compiler.definitions.IPackageDefinition) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) IVariableDefinition(org.apache.flex.compiler.definitions.IVariableDefinition) SymbolInformation(org.eclipse.lsp4j.SymbolInformation) IDefinition(org.apache.flex.compiler.definitions.IDefinition)

Example 3 with IASScope

use of org.apache.flex.compiler.scopes.IASScope in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method actionScriptCompletionWithNode.

private CompletableFuture<CompletionList> actionScriptCompletionWithNode(TextDocumentPositionParams position, IASNode offsetNode) {
    CompletionList result = new CompletionList();
    result.setIsIncomplete(false);
    result.setItems(new ArrayList<>());
    if (offsetNode == null) {
        //we couldn't find a node at the specified location
        autoCompletePackageBlock(result);
        return CompletableFuture.completedFuture(result);
    }
    IASNode parentNode = offsetNode.getParent();
    IASNode nodeAtPreviousOffset = null;
    if (parentNode != null) {
        nodeAtPreviousOffset = parentNode.getContainingNode(currentOffset - 1);
    }
    if (!isActionScriptCompletionAllowedInNode(position, offsetNode)) {
        //if we're inside a node that shouldn't have completion!
        return CompletableFuture.completedFuture(new CompletionList());
    }
    //variable types
    if (offsetNode instanceof IVariableNode) {
        IVariableNode variableNode = (IVariableNode) offsetNode;
        IExpressionNode nameExpression = variableNode.getNameExpressionNode();
        IExpressionNode typeNode = variableNode.getVariableTypeNode();
        int line = position.getPosition().getLine();
        int column = position.getPosition().getCharacter();
        if (line >= nameExpression.getEndLine() && line <= typeNode.getLine()) {
            if ((line != nameExpression.getEndLine() && line != typeNode.getLine()) || (line == nameExpression.getEndLine() && column > nameExpression.getEndColumn()) || (line == typeNode.getLine() && column <= typeNode.getColumn())) {
                autoCompleteTypes(offsetNode, result);
            }
            return CompletableFuture.completedFuture(result);
        }
    }
    if (parentNode != null && parentNode instanceof IVariableNode) {
        IVariableNode variableNode = (IVariableNode) parentNode;
        if (offsetNode == variableNode.getVariableTypeNode()) {
            autoCompleteTypes(parentNode, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    //function return types
    if (offsetNode instanceof IFunctionNode) {
        IFunctionNode functionNode = (IFunctionNode) offsetNode;
        IContainerNode parameters = functionNode.getParametersContainerNode();
        IExpressionNode typeNode = functionNode.getReturnTypeNode();
        if (typeNode != null) {
            int line = position.getPosition().getLine();
            int column = position.getPosition().getCharacter();
            if (line >= parameters.getEndLine() && column > parameters.getEndColumn() && line <= typeNode.getLine() && column <= typeNode.getColumn()) {
                autoCompleteTypes(offsetNode, result);
                return CompletableFuture.completedFuture(result);
            }
        }
    }
    if (parentNode != null && parentNode instanceof IFunctionNode) {
        IFunctionNode functionNode = (IFunctionNode) parentNode;
        if (offsetNode == functionNode.getReturnTypeNode()) {
            autoCompleteTypes(parentNode, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    //new keyword types
    if (parentNode != null && parentNode instanceof IFunctionCallNode) {
        IFunctionCallNode functionCallNode = (IFunctionCallNode) parentNode;
        if (functionCallNode.getNameNode() == offsetNode && functionCallNode.isNewExpression()) {
            autoCompleteTypes(parentNode, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    if (nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IKeywordNode && nodeAtPreviousOffset.getNodeID() == ASTNodeID.KeywordNewID) {
        autoCompleteTypes(nodeAtPreviousOffset, result);
        return CompletableFuture.completedFuture(result);
    }
    //as and is keyword types
    if (parentNode != null && parentNode instanceof IBinaryOperatorNode && (parentNode.getNodeID() == ASTNodeID.Op_AsID || parentNode.getNodeID() == ASTNodeID.Op_IsID)) {
        IBinaryOperatorNode binaryOperatorNode = (IBinaryOperatorNode) parentNode;
        if (binaryOperatorNode.getRightOperandNode() == offsetNode) {
            autoCompleteTypes(parentNode, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    if (nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IBinaryOperatorNode && (nodeAtPreviousOffset.getNodeID() == ASTNodeID.Op_AsID || nodeAtPreviousOffset.getNodeID() == ASTNodeID.Op_IsID)) {
        autoCompleteTypes(nodeAtPreviousOffset, result);
        return CompletableFuture.completedFuture(result);
    }
    //class extends keyword
    if (offsetNode instanceof IClassNode && nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IKeywordNode && nodeAtPreviousOffset.getNodeID() == ASTNodeID.KeywordExtendsID) {
        autoCompleteTypes(offsetNode, result);
        return CompletableFuture.completedFuture(result);
    }
    //class implements keyword
    if (offsetNode instanceof IClassNode && nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IKeywordNode && nodeAtPreviousOffset.getNodeID() == ASTNodeID.KeywordImplementsID) {
        autoCompleteTypes(offsetNode, result);
        return CompletableFuture.completedFuture(result);
    }
    //interface extends keyword
    if (offsetNode instanceof IInterfaceNode && nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IKeywordNode && nodeAtPreviousOffset.getNodeID() == ASTNodeID.KeywordExtendsID) {
        autoCompleteTypes(offsetNode, result);
        return CompletableFuture.completedFuture(result);
    }
    //package (must be before member access)
    if (offsetNode instanceof IPackageNode) {
        IPackageNode packageNode = (IPackageNode) offsetNode;
        autoCompletePackageName(packageNode.getPackageName(), result);
        return CompletableFuture.completedFuture(result);
    }
    if (parentNode != null && parentNode instanceof FullNameNode) {
        IASNode gpNode = parentNode.getParent();
        if (gpNode != null && gpNode instanceof IPackageNode) {
            IPackageNode packageNode = (IPackageNode) gpNode;
            autoCompletePackageName(packageNode.getPackageName(), result);
        }
    }
    if (parentNode != null && parentNode instanceof IPackageNode) {
        //we'll get here if the last character in the package name is .
        IPackageNode packageNode = (IPackageNode) parentNode;
        IExpressionNode nameNode = packageNode.getNameExpressionNode();
        if (offsetNode == nameNode) {
            autoCompletePackageName(packageNode.getPackageName(), result);
            return CompletableFuture.completedFuture(result);
        }
    }
    //import (must be before member access)
    if (parentNode != null && parentNode instanceof IImportNode) {
        IImportNode importNode = (IImportNode) parentNode;
        IExpressionNode nameNode = importNode.getImportNameNode();
        if (offsetNode == nameNode) {
            String importName = importNode.getImportName();
            importName = importName.substring(0, position.getPosition().getCharacter() - nameNode.getColumn());
            autoCompleteImport(importName, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    if (parentNode != null && parentNode instanceof FullNameNode) {
        IASNode gpNode = parentNode.getParent();
        if (gpNode != null && gpNode instanceof IImportNode) {
            IImportNode importNode = (IImportNode) gpNode;
            IExpressionNode nameNode = importNode.getImportNameNode();
            if (parentNode == nameNode) {
                String importName = importNode.getImportName();
                importName = importName.substring(0, position.getPosition().getCharacter() - nameNode.getColumn());
                autoCompleteImport(importName, result);
                return CompletableFuture.completedFuture(result);
            }
        }
    }
    if (nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IImportNode) {
        autoCompleteImport("", result);
        return CompletableFuture.completedFuture(result);
    }
    //member access
    if (offsetNode instanceof IMemberAccessExpressionNode) {
        IMemberAccessExpressionNode memberAccessNode = (IMemberAccessExpressionNode) offsetNode;
        IExpressionNode leftOperand = memberAccessNode.getLeftOperandNode();
        IExpressionNode rightOperand = memberAccessNode.getRightOperandNode();
        int line = position.getPosition().getLine();
        int column = position.getPosition().getCharacter();
        if (line >= leftOperand.getEndLine() && line <= rightOperand.getLine()) {
            if ((line != leftOperand.getEndLine() && line != rightOperand.getLine()) || (line == leftOperand.getEndLine() && column > leftOperand.getEndColumn()) || (line == rightOperand.getLine() && column <= rightOperand.getColumn())) {
                autoCompleteMemberAccess(memberAccessNode, result);
                return CompletableFuture.completedFuture(result);
            }
        }
    }
    if (parentNode != null && parentNode instanceof IMemberAccessExpressionNode) {
        IMemberAccessExpressionNode memberAccessNode = (IMemberAccessExpressionNode) parentNode;
        //you would expect that the offset node could only be the right
        //operand, but it's actually possible for it to be the left operand,
        //even if the . has been typed! only sometimes, though.
        boolean isValidLeft = true;
        if (offsetNode == memberAccessNode.getLeftOperandNode() && memberAccessNode.getRightOperandNode() instanceof IIdentifierNode) {
            //if the left and right operands both exist, then this is not
            //member access and we should skip ahead
            isValidLeft = false;
        }
        if (offsetNode == memberAccessNode.getRightOperandNode() || isValidLeft) {
            autoCompleteMemberAccess(memberAccessNode, result);
            return CompletableFuture.completedFuture(result);
        }
    }
    if (nodeAtPreviousOffset != null && nodeAtPreviousOffset instanceof IMemberAccessExpressionNode) {
        //depending on the left operand, if a . is typed, the member access
        //may end up being the previous node instead of the parent or offset
        //node, so check if the right operand is empty
        IMemberAccessExpressionNode memberAccessNode = (IMemberAccessExpressionNode) nodeAtPreviousOffset;
        IExpressionNode rightOperandNode = memberAccessNode.getRightOperandNode();
        if (rightOperandNode instanceof IIdentifierNode) {
            IIdentifierNode identifierNode = (IIdentifierNode) rightOperandNode;
            if (identifierNode.getName().equals("")) {
                autoCompleteMemberAccess(memberAccessNode, result);
                return CompletableFuture.completedFuture(result);
            }
        }
    }
    //local scope
    do {
        //nodes to check
        if (offsetNode instanceof IScopedNode) {
            IScopedNode scopedNode = (IScopedNode) offsetNode;
            //include all members and local things that are in scope
            autoCompleteScope(scopedNode, false, result);
            //include all public definitions
            IASScope scope = scopedNode.getScope();
            IDefinition definitionToSkip = scope.getDefinition();
            autoCompleteDefinitions(result, false, false, null, definitionToSkip);
            return CompletableFuture.completedFuture(result);
        }
        offsetNode = offsetNode.getParent();
    } while (offsetNode != null);
    return CompletableFuture.completedFuture(result);
}
Also used : CompletionList(org.eclipse.lsp4j.CompletionList) IScopedNode(org.apache.flex.compiler.tree.as.IScopedNode) IPackageNode(org.apache.flex.compiler.tree.as.IPackageNode) IImportNode(org.apache.flex.compiler.tree.as.IImportNode) IIdentifierNode(org.apache.flex.compiler.tree.as.IIdentifierNode) IKeywordNode(org.apache.flex.compiler.tree.as.IKeywordNode) IVariableNode(org.apache.flex.compiler.tree.as.IVariableNode) IFunctionNode(org.apache.flex.compiler.tree.as.IFunctionNode) IContainerNode(org.apache.flex.compiler.tree.as.IContainerNode) IFunctionCallNode(org.apache.flex.compiler.tree.as.IFunctionCallNode) IInterfaceNode(org.apache.flex.compiler.tree.as.IInterfaceNode) IDefinition(org.apache.flex.compiler.definitions.IDefinition) IASScope(org.apache.flex.compiler.scopes.IASScope) IASNode(org.apache.flex.compiler.tree.as.IASNode) FullNameNode(org.apache.flex.compiler.internal.tree.as.FullNameNode) IClassNode(org.apache.flex.compiler.tree.as.IClassNode) IExpressionNode(org.apache.flex.compiler.tree.as.IExpressionNode) IBinaryOperatorNode(org.apache.flex.compiler.tree.as.IBinaryOperatorNode) IMemberAccessExpressionNode(org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode)

Example 4 with IASScope

use of org.apache.flex.compiler.scopes.IASScope in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method scopeToSymbols.

private void scopeToSymbols(IASScope scope, List<SymbolInformation> result) {
    Collection<IDefinition> definitions = scope.getAllLocalDefinitions();
    for (IDefinition definition : definitions) {
        if (definition instanceof IPackageDefinition) {
            IPackageDefinition packageDefinition = (IPackageDefinition) definition;
            IASScope packageScope = packageDefinition.getContainedScope();
            scopeToSymbols(packageScope, result);
        } else if (definition instanceof ITypeDefinition) {
            ITypeDefinition typeDefinition = (ITypeDefinition) definition;
            if (!definition.isImplicit()) {
                SymbolInformation typeSymbol = definitionToSymbol(typeDefinition);
                result.add(typeSymbol);
            }
            IASScope typeScope = typeDefinition.getContainedScope();
            scopeToSymbols(typeScope, result);
        } else if (definition instanceof IFunctionDefinition || definition instanceof IVariableDefinition) {
            if (definition.isImplicit()) {
                continue;
            }
            SymbolInformation localSymbol = definitionToSymbol(definition);
            result.add(localSymbol);
        }
    }
}
Also used : IFunctionDefinition(org.apache.flex.compiler.definitions.IFunctionDefinition) IASScope(org.apache.flex.compiler.scopes.IASScope) IPackageDefinition(org.apache.flex.compiler.definitions.IPackageDefinition) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) IVariableDefinition(org.apache.flex.compiler.definitions.IVariableDefinition) SymbolInformation(org.eclipse.lsp4j.SymbolInformation) IDefinition(org.apache.flex.compiler.definitions.IDefinition)

Example 5 with IASScope

use of org.apache.flex.compiler.scopes.IASScope in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method autoCompleteScope.

private void autoCompleteScope(IScopedNode node, boolean typesOnly, CompletionList result) {
    IScopedNode currentNode = node;
    ASScope scope = (ASScope) node.getScope();
    while (currentNode != null) {
        IASScope currentScope = currentNode.getScope();
        boolean isType = currentScope instanceof TypeScope;
        boolean staticOnly = currentNode == node && isType;
        if (currentScope instanceof TypeScope && !typesOnly) {
            TypeScope typeScope = (TypeScope) currentScope;
            addDefinitionsInTypeScopeToAutoComplete(typeScope, scope, true, true, false, null, result);
            if (!staticOnly) {
                addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, false, result);
            }
        } else {
            for (IDefinition localDefinition : currentScope.getAllLocalDefinitions()) {
                if (localDefinition.getBaseName().length() == 0) {
                    continue;
                }
                if (typesOnly && !(localDefinition instanceof ITypeDefinition)) {
                    continue;
                }
                if (!staticOnly || localDefinition.isStatic()) {
                    if (localDefinition instanceof ISetterDefinition) {
                        ISetterDefinition setter = (ISetterDefinition) localDefinition;
                        IGetterDefinition getter = setter.resolveGetter(currentProject);
                        if (getter != null) {
                            //it would add a duplicate entry
                            continue;
                        }
                    }
                    addDefinitionAutoCompleteActionScript(localDefinition, result);
                }
            }
        }
        currentNode = currentNode.getContainingScope();
    }
}
Also used : IScopedNode(org.apache.flex.compiler.tree.as.IScopedNode) IASScope(org.apache.flex.compiler.scopes.IASScope) IASScope(org.apache.flex.compiler.scopes.IASScope) ASScope(org.apache.flex.compiler.internal.scopes.ASScope) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) ISetterDefinition(org.apache.flex.compiler.definitions.ISetterDefinition) IGetterDefinition(org.apache.flex.compiler.definitions.IGetterDefinition) TypeScope(org.apache.flex.compiler.internal.scopes.TypeScope) IDefinition(org.apache.flex.compiler.definitions.IDefinition)

Aggregations

IASScope (org.apache.flex.compiler.scopes.IASScope)9 IDefinition (org.apache.flex.compiler.definitions.IDefinition)6 FileNotFoundException (java.io.FileNotFoundException)4 IOException (java.io.IOException)4 ConcurrentModificationException (java.util.ConcurrentModificationException)4 ICompilationUnit (org.apache.flex.compiler.units.ICompilationUnit)4 SymbolInformation (org.eclipse.lsp4j.SymbolInformation)4 ArrayList (java.util.ArrayList)3 IFunctionDefinition (org.apache.flex.compiler.definitions.IFunctionDefinition)3 ITypeDefinition (org.apache.flex.compiler.definitions.ITypeDefinition)3 Path (java.nio.file.Path)2 IPackageDefinition (org.apache.flex.compiler.definitions.IPackageDefinition)2 IVariableDefinition (org.apache.flex.compiler.definitions.IVariableDefinition)2 ASScope (org.apache.flex.compiler.internal.scopes.ASScope)2 TypeScope (org.apache.flex.compiler.internal.scopes.TypeScope)2 IScopedNode (org.apache.flex.compiler.tree.as.IScopedNode)2 ISourceLocation (org.apache.flex.compiler.common.ISourceLocation)1 IClassDefinition (org.apache.flex.compiler.definitions.IClassDefinition)1 IGetterDefinition (org.apache.flex.compiler.definitions.IGetterDefinition)1 ISetterDefinition (org.apache.flex.compiler.definitions.ISetterDefinition)1