Search in sources :

Example 1 with IASNode

use of org.apache.flex.compiler.tree.as.IASNode in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method completion.

/**
     * Returns a list of all items to display in the completion list at a
     * specific position in a document. Called automatically by VSCode as the
     * user types, and may not necessarily be triggered only on "." or ":".
     */
@Override
public CompletableFuture<CompletionList> completion(TextDocumentPositionParams position) {
    String textDocumentUri = position.getTextDocument().getUri();
    if (!textDocumentUri.endsWith(AS_EXTENSION) && !textDocumentUri.endsWith(MXML_EXTENSION)) {
        CompletionList result = new CompletionList();
        result.setIsIncomplete(false);
        result.setItems(new ArrayList<>());
        return CompletableFuture.completedFuture(result);
    }
    IMXMLTagData offsetTag = getOffsetMXMLTag(position);
    if (offsetTag != null) {
        IASNode embeddedNode = getEmbeddedActionScriptNodeInMXMLTag(offsetTag, currentOffset, position);
        if (embeddedNode != null) {
            return actionScriptCompletionWithNode(position, embeddedNode);
        }
        //so that's why we call isMXMLTagValidForCompletion()
        if (isMXMLTagValidForCompletion(offsetTag)) {
            return mxmlCompletion(position, offsetTag);
        }
    }
    if (offsetTag == null && position.getTextDocument().getUri().endsWith(MXML_EXTENSION)) {
        //it's possible for the offset tag to be null in an MXML file, but
        //we don't want to trigger ActionScript completion.
        //for some reason, the offset tag will be null if completion is
        //triggered at the asterisk:
        //<fx:Declarations>*
        CompletionList result = new CompletionList();
        result.setIsIncomplete(false);
        result.setItems(new ArrayList<>());
        return CompletableFuture.completedFuture(result);
    }
    return actionScriptCompletion(position);
}
Also used : CompletionList(org.eclipse.lsp4j.CompletionList) IASNode(org.apache.flex.compiler.tree.as.IASNode) IMXMLTagData(org.apache.flex.compiler.mxml.IMXMLTagData)

Example 2 with IASNode

use of org.apache.flex.compiler.tree.as.IASNode in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method getOffsetNode.

private IASNode getOffsetNode(TextDocumentIdentifier textDocument, Position position) {
    currentOffset = -1;
    if (!textDocument.getUri().endsWith(MXML_EXTENSION)) {
        //if we're in an <fx:Script> element, these will have been
        //previously calculated, so don't clear them
        importStartIndex = -1;
        importEndIndex = -1;
    }
    Path path = LanguageServerUtils.getPathFromLanguageServerURI(textDocument.getUri());
    if (path == null) {
        return null;
    }
    if (!isInWorkspaceOrSourcePath(path)) {
        //the path must be in the workspace or source-path
        return null;
    }
    String code;
    if (sourceByPath.containsKey(path)) {
        code = sourceByPath.get(path);
    } else {
        System.err.println("Could not find source " + path.toAbsolutePath().toString());
        System.err.println(sourceByPath.keySet().size());
        return null;
    }
    ICompilationUnit unit = getCompilationUnit(path);
    if (unit == null) {
        //should have been logged already
        return null;
    }
    IASNode ast = null;
    try {
        ast = unit.getSyntaxTreeRequest().get().getAST();
    } catch (InterruptedException e) {
        System.err.println("Interrupted while getting AST: " + path.toAbsolutePath().toString());
        return null;
    }
    if (ast == null) {
        //we couldn't find the root node for this file
        System.err.println("Could not find AST: " + path.toAbsolutePath().toString());
        return null;
    }
    currentOffset = lineAndCharacterToOffset(new StringReader(code), position.getLine(), position.getCharacter());
    if (currentOffset == -1) {
        System.err.println("Could not find code at position " + position.getLine() + ":" + position.getCharacter() + " in file " + path.toAbsolutePath().toString());
        return null;
    }
    IASNode offsetNode = getContainingNodeIncludingStart(ast, currentOffset);
    if (offsetNode != null) {
        //if we have an offset node, try to find where imports may be added
        IPackageNode packageNode = (IPackageNode) offsetNode.getAncestorOfType(IPackageNode.class);
        if (packageNode == null) {
            IFileNode fileNode = (IFileNode) offsetNode.getAncestorOfType(IFileNode.class);
            if (fileNode != null) {
                boolean foundPackage = false;
                for (int i = 0; i < fileNode.getChildCount(); i++) {
                    IASNode childNode = fileNode.getChild(i);
                    if (foundPackage) {
                        //this is the node following the package
                        importStartIndex = childNode.getAbsoluteStart();
                        break;
                    }
                    if (childNode instanceof IPackageNode) {
                        //use the start of the the next node after the
                        //package as the place where the import can be added
                        foundPackage = true;
                    }
                }
            }
        } else {
            importEndIndex = packageNode.getAbsoluteEnd();
        }
    }
    return offsetNode;
}
Also used : Path(java.nio.file.Path) ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) IPackageNode(org.apache.flex.compiler.tree.as.IPackageNode) IFileNode(org.apache.flex.compiler.tree.as.IFileNode) IASNode(org.apache.flex.compiler.tree.as.IASNode) StringReader(java.io.StringReader)

Example 3 with IASNode

use of org.apache.flex.compiler.tree.as.IASNode in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method getEmbeddedActionScriptNodeInMXMLTag.

private IASNode getEmbeddedActionScriptNodeInMXMLTag(IMXMLTagData tag, int offset, TextDocumentPositionParams position) {
    IMXMLTagAttributeData attributeData = getMXMLTagAttributeWithValueAtOffset(tag, currentOffset);
    if (attributeData != null) {
        //some attributes can have ActionScript completion, such as
        //events and properties with data binding
        IClassDefinition tagDefinition = (IClassDefinition) currentProject.resolveXMLNameToDefinition(tag.getXMLName(), tag.getMXMLDialect());
        IDefinition attributeDefinition = currentProject.resolveSpecifier(tagDefinition, attributeData.getShortName());
        if (attributeDefinition instanceof IEventDefinition) {
            IMXMLInstanceNode mxmlNode = (IMXMLInstanceNode) getOffsetNode(position);
            IMXMLEventSpecifierNode eventNode = mxmlNode.getEventSpecifierNode(attributeData.getShortName());
            for (IASNode asNode : eventNode.getASNodes()) {
                IASNode containingNode = getContainingNodeIncludingStart(asNode, currentOffset);
                if (containingNode != null) {
                    return containingNode;
                }
            }
            return eventNode;
        } else {
            IASNode offsetNode = getOffsetNode(position);
            if (offsetNode instanceof IMXMLInstanceNode) {
                IMXMLInstanceNode instanceNode = (IMXMLInstanceNode) offsetNode;
                IMXMLPropertySpecifierNode propertyNode = instanceNode.getPropertySpecifierNode(attributeData.getShortName());
                if (propertyNode != null) {
                    for (int i = 0, count = propertyNode.getChildCount(); i < count; i++) {
                        IMXMLNode propertyChild = (IMXMLNode) propertyNode.getChild(i);
                        if (propertyChild instanceof IMXMLConcatenatedDataBindingNode) {
                            IMXMLConcatenatedDataBindingNode dataBinding = (IMXMLConcatenatedDataBindingNode) propertyChild;
                            for (int j = 0, childCount = dataBinding.getChildCount(); j < childCount; j++) {
                                IASNode dataBindingChild = dataBinding.getChild(i);
                                if (dataBindingChild.contains(currentOffset) && dataBindingChild instanceof IMXMLSingleDataBindingNode) {
                                    //we'll parse this in a moment, as if it were
                                    //a direct child of the property specifier
                                    propertyChild = (IMXMLSingleDataBindingNode) dataBindingChild;
                                    break;
                                }
                            }
                        }
                        if (propertyChild instanceof IMXMLSingleDataBindingNode) {
                            IMXMLSingleDataBindingNode dataBinding = (IMXMLSingleDataBindingNode) propertyChild;
                            IASNode containingNode = dataBinding.getExpressionNode().getContainingNode(currentOffset);
                        //we found the correct expression, but due to a bug
                        //in the compiler its line and column positions
                        //will be wrong. the resulting completion is too
                        //quirky, so this feature will be completed later.
                        //return containingNode;
                        }
                    }
                }
            }
        //nothing possible for this attribute
        }
    }
    return null;
}
Also used : IMXMLConcatenatedDataBindingNode(org.apache.flex.compiler.tree.mxml.IMXMLConcatenatedDataBindingNode) IMXMLEventSpecifierNode(org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode) IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) IMXMLInstanceNode(org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode) IASNode(org.apache.flex.compiler.tree.as.IASNode) IMXMLSingleDataBindingNode(org.apache.flex.compiler.tree.mxml.IMXMLSingleDataBindingNode) IMXMLPropertySpecifierNode(org.apache.flex.compiler.tree.mxml.IMXMLPropertySpecifierNode) IEventDefinition(org.apache.flex.compiler.definitions.IEventDefinition) IDefinition(org.apache.flex.compiler.definitions.IDefinition) IMXMLNode(org.apache.flex.compiler.tree.mxml.IMXMLNode) IMXMLTagAttributeData(org.apache.flex.compiler.mxml.IMXMLTagAttributeData)

Example 4 with IASNode

use of org.apache.flex.compiler.tree.as.IASNode in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method findIdentifiers.

private void findIdentifiers(IASNode node, IDefinition definition, List<IIdentifierNode> result) {
    if (node.isTerminal()) {
        if (node instanceof IIdentifierNode) {
            IIdentifierNode identifierNode = (IIdentifierNode) node;
            if (identifierNode.resolve(currentProject) == definition) {
                result.add(identifierNode);
            }
        }
        return;
    }
    for (int i = 0, count = node.getChildCount(); i < count; i++) {
        IASNode childNode = node.getChild(i);
        findIdentifiers(childNode, definition, result);
    }
}
Also used : IASNode(org.apache.flex.compiler.tree.as.IASNode) IIdentifierNode(org.apache.flex.compiler.tree.as.IIdentifierNode)

Example 5 with IASNode

use of org.apache.flex.compiler.tree.as.IASNode in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method hover.

/**
     * Returns information to display in a tooltip when the mouse hovers over
     * something in a text document.
     */
@Override
public CompletableFuture<Hover> hover(TextDocumentPositionParams position) {
    String textDocumentUri = position.getTextDocument().getUri();
    if (!textDocumentUri.endsWith(AS_EXTENSION) && !textDocumentUri.endsWith(MXML_EXTENSION)) {
        return CompletableFuture.completedFuture(new Hover(Collections.emptyList(), null));
    }
    IMXMLTagData offsetTag = getOffsetMXMLTag(position);
    if (offsetTag != null) {
        IASNode embeddedNode = getEmbeddedActionScriptNodeInMXMLTag(offsetTag, currentOffset, position);
        if (embeddedNode != null) {
            return actionScriptHoverWithNode(position, embeddedNode);
        }
        //so that's why we call isMXMLTagValidForCompletion()
        if (isMXMLTagValidForCompletion(offsetTag)) {
            return mxmlHover(position, offsetTag);
        }
    }
    return actionScriptHover(position);
}
Also used : IASNode(org.apache.flex.compiler.tree.as.IASNode) Hover(org.eclipse.lsp4j.Hover) IMXMLTagData(org.apache.flex.compiler.mxml.IMXMLTagData)

Aggregations

IASNode (org.apache.flex.compiler.tree.as.IASNode)16 IMXMLTagData (org.apache.flex.compiler.mxml.IMXMLTagData)8 IIdentifierNode (org.apache.flex.compiler.tree.as.IIdentifierNode)5 ICompilationUnit (org.apache.flex.compiler.units.ICompilationUnit)5 IDefinition (org.apache.flex.compiler.definitions.IDefinition)4 FileNotFoundException (java.io.FileNotFoundException)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 ConcurrentModificationException (java.util.ConcurrentModificationException)3 HashMap (java.util.HashMap)3 SWCCompilationUnit (org.apache.flex.compiler.internal.units.SWCCompilationUnit)3 CompletionList (org.eclipse.lsp4j.CompletionList)3 URI (java.net.URI)2 ISourceLocation (org.apache.flex.compiler.common.ISourceLocation)2 IClassDefinition (org.apache.flex.compiler.definitions.IClassDefinition)2 IEventDefinition (org.apache.flex.compiler.definitions.IEventDefinition)2 MXMLData (org.apache.flex.compiler.internal.mxml.MXMLData)2 IMXMLDataManager (org.apache.flex.compiler.mxml.IMXMLDataManager)2 IMXMLTagAttributeData (org.apache.flex.compiler.mxml.IMXMLTagAttributeData)2 IExpressionNode (org.apache.flex.compiler.tree.as.IExpressionNode)2