Search in sources :

Example 1 with IClassDefinition

use of org.apache.flex.compiler.definitions.IClassDefinition 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 IClassDefinition

use of org.apache.flex.compiler.definitions.IClassDefinition in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method autoCompleteImport.

private void autoCompleteImport(String importName, CompletionList result) {
    List<CompletionItem> items = result.getItems();
    for (ICompilationUnit unit : compilationUnits) {
        if (unit == null) {
            continue;
        }
        Collection<IDefinition> definitions = null;
        try {
            definitions = unit.getFileScopeRequest().get().getExternallyVisibleDefinitions();
        } catch (Exception e) {
            //safe to ignore
            continue;
        }
        for (IDefinition definition : definitions) {
            if (definition instanceof ITypeDefinition) {
                String qualifiedName = definition.getQualifiedName();
                if (qualifiedName.equals(definition.getBaseName())) {
                    //this definition is top-level. no import required.
                    continue;
                }
                if (qualifiedName.startsWith(importName)) {
                    int index = importName.lastIndexOf(".");
                    if (index != -1) {
                        qualifiedName = qualifiedName.substring(index + 1);
                    }
                    index = qualifiedName.indexOf(".");
                    if (index > 0) {
                        qualifiedName = qualifiedName.substring(0, index);
                    }
                    CompletionItem item = new CompletionItem();
                    item.setLabel(qualifiedName);
                    if (definition.getBaseName().equals(qualifiedName)) {
                        ITypeDefinition typeDefinition = (ITypeDefinition) definition;
                        if (typeDefinition instanceof IInterfaceDefinition) {
                            item.setKind(CompletionItemKind.Interface);
                        } else if (typeDefinition instanceof IClassDefinition) {
                            item.setKind(CompletionItemKind.Class);
                        } else {
                            item.setKind(CompletionItemKind.Text);
                        }
                    } else {
                        item.setKind(CompletionItemKind.Text);
                    }
                    if (!items.contains(item)) {
                        items.add(item);
                    }
                }
            }
        }
    }
}
Also used : ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) IInterfaceDefinition(org.apache.flex.compiler.definitions.IInterfaceDefinition) IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) CompletionItem(org.eclipse.lsp4j.CompletionItem) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) IDefinition(org.apache.flex.compiler.definitions.IDefinition) ConcurrentModificationException(java.util.ConcurrentModificationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Example 3 with IClassDefinition

use of org.apache.flex.compiler.definitions.IClassDefinition in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method mxmlCompletion.

private CompletableFuture<CompletionList> mxmlCompletion(TextDocumentPositionParams position, IMXMLTagData offsetTag) {
    CompletionList result = new CompletionList();
    result.setIsIncomplete(false);
    result.setItems(new ArrayList<>());
    if (isInXMLComment(position)) {
        //if we're inside a comment, no completion!
        return CompletableFuture.completedFuture(result);
    }
    IMXMLTagData parentTag = offsetTag.getParentTag();
    //for some reason, the attributes list includes the >, but that's not
    //what we want here, so check if currentOffset isn't the end of the tag!
    boolean isAttribute = offsetTag.isOffsetInAttributeList(currentOffset) && currentOffset < offsetTag.getAbsoluteEnd();
    if (isAttribute && offsetTag.isCloseTag()) {
        return CompletableFuture.completedFuture(result);
    }
    //inside <fx:Declarations>
    if (isDeclarationsTag(offsetTag)) {
        if (!isAttribute) {
            autoCompleteTypesForMXML(result);
        }
        return CompletableFuture.completedFuture(result);
    }
    IDefinition offsetDefinition = getDefinitionForMXMLTag(offsetTag);
    if (offsetDefinition == null) {
        IDefinition parentDefinition = null;
        if (parentTag != null) {
            parentDefinition = getDefinitionForMXMLTag(parentTag);
        }
        if (parentDefinition != null) {
            if (parentDefinition instanceof IClassDefinition) {
                IClassDefinition classDefinition = (IClassDefinition) parentDefinition;
                String offsetPrefix = offsetTag.getPrefix();
                if (offsetPrefix.length() == 0 || parentTag.getPrefix().equals(offsetPrefix)) {
                    //only add members if the prefix is the same as the
                    //parent tag. members can't have different prefixes.
                    //also allow members when we don't have a prefix.
                    addMembersForMXMLTypeToAutoComplete(classDefinition, parentTag, offsetPrefix.length() == 0, result);
                }
                if (!isAttribute) {
                    //tags can't appear in attributes, so skip types
                    String defaultPropertyName = classDefinition.getDefaultPropertyName(currentProject);
                    if (defaultPropertyName != null) {
                        //only add types if the class defines [DefaultProperty]
                        //metadata
                        autoCompleteTypesForMXMLFromExistingTag(result, offsetTag);
                    }
                }
            } else {
                //the parent is something like a property, so matching the
                //prefix is not required
                autoCompleteTypesForMXMLFromExistingTag(result, offsetTag);
            }
            return CompletableFuture.completedFuture(result);
        } else if (isDeclarationsTag(parentTag)) {
            autoCompleteTypesForMXMLFromExistingTag(result, offsetTag);
            return CompletableFuture.completedFuture(result);
        }
        return CompletableFuture.completedFuture(result);
    }
    if (offsetDefinition instanceof IClassDefinition) {
        IMXMLTagAttributeData attribute = getMXMLTagAttributeWithValueAtOffset(offsetTag, currentOffset);
        if (attribute != null) {
            return mxmlAttributeCompletion(offsetTag, result);
        }
        IClassDefinition classDefinition = (IClassDefinition) offsetDefinition;
        addMembersForMXMLTypeToAutoComplete(classDefinition, offsetTag, !isAttribute, result);
        String defaultPropertyName = classDefinition.getDefaultPropertyName(currentProject);
        if (defaultPropertyName != null && !isAttribute) {
            //if [DefaultProperty] is set, then we can instantiate
            //types as child elements
            //but we don't want to do that when in an attribute
            autoCompleteTypesForMXML(result);
        }
        return CompletableFuture.completedFuture(result);
    }
    if (offsetDefinition instanceof IVariableDefinition || offsetDefinition instanceof IEventDefinition || offsetDefinition instanceof IStyleDefinition) {
        if (!isAttribute) {
            autoCompleteTypesForMXML(result);
        }
        return CompletableFuture.completedFuture(result);
    }
    System.err.println("Unknown definition for MXML completion: " + offsetDefinition.getClass());
    return CompletableFuture.completedFuture(result);
}
Also used : CompletionList(org.eclipse.lsp4j.CompletionList) IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) IVariableDefinition(org.apache.flex.compiler.definitions.IVariableDefinition) IStyleDefinition(org.apache.flex.compiler.definitions.IStyleDefinition) IMXMLTagData(org.apache.flex.compiler.mxml.IMXMLTagData) IEventDefinition(org.apache.flex.compiler.definitions.IEventDefinition) IDefinition(org.apache.flex.compiler.definitions.IDefinition) IMXMLTagAttributeData(org.apache.flex.compiler.mxml.IMXMLTagAttributeData)

Example 4 with IClassDefinition

use of org.apache.flex.compiler.definitions.IClassDefinition 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 5 with IClassDefinition

use of org.apache.flex.compiler.definitions.IClassDefinition in project vscode-nextgenas by BowlerHatLLC.

the class ActionScriptTextDocumentService method addStyleMetadataToAutoCompleteMXML.

private void addStyleMetadataToAutoCompleteMXML(TypeScope typeScope, String prefix, CompletionList result) {
    ArrayList<String> styleNames = new ArrayList<>();
    IDefinition definition = typeScope.getDefinition();
    List<CompletionItem> items = result.getItems();
    while (definition instanceof IClassDefinition) {
        IClassDefinition classDefinition = (IClassDefinition) definition;
        IMetaTag[] styleMetaTags = typeScope.getDefinition().getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_STYLE);
        for (IMetaTag styleMetaTag : styleMetaTags) {
            String styleName = styleMetaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_NAME);
            if (styleNames.contains(styleName)) {
                //avoid duplicates!
                continue;
            }
            styleNames.add(styleName);
            IDefinition styleDefinition = currentProject.resolveSpecifier(classDefinition, styleName);
            if (styleDefinition == null) {
                continue;
            }
            boolean foundExisting = false;
            for (CompletionItem item : items) {
                if (item.getLabel().equals(styleName)) {
                    //we want to avoid adding a duplicate item with the same
                    //name. if there's a conflict, the compiler will know
                    //how to handle it.
                    foundExisting = true;
                    break;
                }
            }
            if (foundExisting) {
                break;
            }
            CompletionItem item = new CompletionItem();
            item.setKind(CompletionItemKind.Field);
            item.setLabel(styleName);
            if (prefix != null) {
                item.setInsertText(prefix + IMXMLCoreConstants.colon + styleName);
            }
            item.setDetail(getDefinitionDetail(styleDefinition));
            items.add(item);
        }
        definition = classDefinition.resolveBaseClass(currentProject);
    }
}
Also used : IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) IMetaTag(org.apache.flex.compiler.definitions.metadata.IMetaTag) CompletionItem(org.eclipse.lsp4j.CompletionItem) ArrayList(java.util.ArrayList) IDefinition(org.apache.flex.compiler.definitions.IDefinition)

Aggregations

IClassDefinition (org.apache.flex.compiler.definitions.IClassDefinition)13 IDefinition (org.apache.flex.compiler.definitions.IDefinition)12 IMXMLTagAttributeData (org.apache.flex.compiler.mxml.IMXMLTagAttributeData)6 ArrayList (java.util.ArrayList)5 IEventDefinition (org.apache.flex.compiler.definitions.IEventDefinition)4 IFunctionDefinition (org.apache.flex.compiler.definitions.IFunctionDefinition)4 IInterfaceDefinition (org.apache.flex.compiler.definitions.IInterfaceDefinition)4 IMXMLTagData (org.apache.flex.compiler.mxml.IMXMLTagData)4 ITypeDefinition (org.apache.flex.compiler.definitions.ITypeDefinition)3 IMetaTag (org.apache.flex.compiler.definitions.metadata.IMetaTag)3 CompletionItem (org.eclipse.lsp4j.CompletionItem)3 FileNotFoundException (java.io.FileNotFoundException)2 IOException (java.io.IOException)2 Path (java.nio.file.Path)2 ConcurrentModificationException (java.util.ConcurrentModificationException)2 ISourceLocation (org.apache.flex.compiler.common.ISourceLocation)2 IConstantDefinition (org.apache.flex.compiler.definitions.IConstantDefinition)2 IParameterDefinition (org.apache.flex.compiler.definitions.IParameterDefinition)2 IStyleDefinition (org.apache.flex.compiler.definitions.IStyleDefinition)2 IVariableDefinition (org.apache.flex.compiler.definitions.IVariableDefinition)2