Search in sources :

Example 11 with IDefinition

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

the class ActionScriptTextDocumentService method autoCompleteDefinitions.

private void autoCompleteDefinitions(CompletionList result, boolean forMXML, boolean typesOnly, String packageName, IDefinition definitionToSkip) {
    String skipQualifiedName = null;
    if (definitionToSkip != null) {
        skipQualifiedName = definitionToSkip.getQualifiedName();
    }
    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) {
            boolean isType = definition instanceof ITypeDefinition;
            if (!typesOnly || isType) {
                if (packageName == null || definition.getPackageName().equals(packageName)) {
                    if (skipQualifiedName != null && skipQualifiedName.equals(definition.getQualifiedName())) {
                        continue;
                    }
                    if (isType) {
                        IMetaTag excludeClassMetaTag = definition.getMetaTagByName(IMetaAttributeConstants.ATTRIBUTE_EXCLUDECLASS);
                        if (excludeClassMetaTag != null) {
                            //skip types with [ExcludeClass] metadata
                            continue;
                        }
                    }
                    if (forMXML && isType) {
                        ITypeDefinition typeDefinition = (ITypeDefinition) definition;
                        addMXMLTypeDefinitionAutoComplete(typeDefinition, result);
                    } else {
                        addDefinitionAutoCompleteActionScript(definition, result);
                    }
                }
            }
        }
    }
    if (packageName == null || packageName.equals("")) {
        CompletionItem item = new CompletionItem();
        item.setKind(CompletionItemKind.Class);
        item.setLabel(IASKeywordConstants.VOID);
        result.getItems().add(item);
    }
}
Also used : ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) IMetaTag(org.apache.flex.compiler.definitions.metadata.IMetaTag) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) CompletionItem(org.eclipse.lsp4j.CompletionItem) IDefinition(org.apache.flex.compiler.definitions.IDefinition) ConcurrentModificationException(java.util.ConcurrentModificationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Example 12 with IDefinition

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

the class ActionScriptTextDocumentService method signatureHelp.

/**
     * Displays a function's parameters, including which one is currently
     * active. Called automatically by VSCode any time that the user types "(",
     * so be sure to check that a function call is actually happening at the
     * current position.
     */
@Override
public CompletableFuture<SignatureHelp> signatureHelp(TextDocumentPositionParams position) {
    String textDocumentUri = position.getTextDocument().getUri();
    if (!textDocumentUri.endsWith(AS_EXTENSION) && !textDocumentUri.endsWith(MXML_EXTENSION)) {
        //we couldn't find a node at the specified location
        return CompletableFuture.completedFuture(new SignatureHelp(Collections.emptyList(), -1, -1));
    }
    IASNode offsetNode = null;
    IMXMLTagData offsetTag = getOffsetMXMLTag(position);
    if (offsetTag != null) {
        IMXMLTagAttributeData attributeData = getMXMLTagAttributeWithValueAtOffset(offsetTag, currentOffset);
        if (attributeData != null) {
            //some attributes can have ActionScript completion, such as
            //events and properties with data binding
            IClassDefinition tagDefinition = (IClassDefinition) currentProject.resolveXMLNameToDefinition(offsetTag.getXMLName(), offsetTag.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) {
                        offsetNode = containingNode;
                    }
                }
                if (offsetNode == null) {
                    offsetNode = eventNode;
                }
            }
        }
    }
    if (offsetNode == null) {
        offsetNode = getOffsetNode(position);
    }
    if (offsetNode == null) {
        //we couldn't find a node at the specified location
        return CompletableFuture.completedFuture(new SignatureHelp(Collections.emptyList(), -1, -1));
    }
    IFunctionCallNode functionCallNode = getAncestorFunctionCallNode(offsetNode);
    IFunctionDefinition functionDefinition = null;
    if (functionCallNode != null) {
        IExpressionNode nameNode = functionCallNode.getNameNode();
        IDefinition definition = nameNode.resolve(currentUnit.getProject());
        if (definition instanceof IFunctionDefinition) {
            functionDefinition = (IFunctionDefinition) definition;
        } else if (definition instanceof IClassDefinition) {
            IClassDefinition classDefinition = (IClassDefinition) definition;
            functionDefinition = classDefinition.getConstructor();
        } else if (nameNode instanceof IIdentifierNode) {
            //special case for super()
            IIdentifierNode identifierNode = (IIdentifierNode) nameNode;
            if (identifierNode.getName().equals(IASKeywordConstants.SUPER)) {
                ITypeDefinition typeDefinition = nameNode.resolveType(currentProject);
                if (typeDefinition instanceof IClassDefinition) {
                    IClassDefinition classDefinition = (IClassDefinition) typeDefinition;
                    functionDefinition = classDefinitionToConstructor(classDefinition);
                }
            }
        }
    }
    if (functionDefinition != null) {
        SignatureHelp result = new SignatureHelp();
        List<SignatureInformation> signatures = new ArrayList<>();
        SignatureInformation signatureInfo = new SignatureInformation();
        signatureInfo.setLabel(getSignatureLabel(functionDefinition));
        List<ParameterInformation> parameters = new ArrayList<>();
        for (IParameterDefinition param : functionDefinition.getParameters()) {
            ParameterInformation paramInfo = new ParameterInformation();
            paramInfo.setLabel(param.getBaseName());
            parameters.add(paramInfo);
        }
        signatureInfo.setParameters(parameters);
        signatures.add(signatureInfo);
        result.setSignatures(signatures);
        result.setActiveSignature(0);
        int index = getFunctionCallNodeArgumentIndex(functionCallNode, offsetNode);
        IParameterDefinition[] params = functionDefinition.getParameters();
        int paramCount = params.length;
        if (paramCount > 0 && index >= paramCount) {
            if (index >= paramCount) {
                IParameterDefinition lastParam = params[paramCount - 1];
                if (lastParam.isRest()) {
                    //functions with rest parameters may accept any
                    //number of arguments, so continue to make the rest
                    //parameter active
                    index = paramCount - 1;
                } else {
                    //if there's no rest parameter, and we're beyond the
                    //final parameter, none should be active
                    index = -1;
                }
            }
        }
        if (index != -1) {
            result.setActiveParameter(index);
        }
        return CompletableFuture.completedFuture(result);
    }
    return CompletableFuture.completedFuture(new SignatureHelp(Collections.emptyList(), -1, -1));
}
Also used : IMXMLEventSpecifierNode(org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode) IClassDefinition(org.apache.flex.compiler.definitions.IClassDefinition) IMXMLInstanceNode(org.apache.flex.compiler.tree.mxml.IMXMLInstanceNode) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) ArrayList(java.util.ArrayList) IIdentifierNode(org.apache.flex.compiler.tree.as.IIdentifierNode) SignatureHelp(org.eclipse.lsp4j.SignatureHelp) IMXMLTagData(org.apache.flex.compiler.mxml.IMXMLTagData) IFunctionCallNode(org.apache.flex.compiler.tree.as.IFunctionCallNode) ParameterInformation(org.eclipse.lsp4j.ParameterInformation) IDefinition(org.apache.flex.compiler.definitions.IDefinition) IFunctionDefinition(org.apache.flex.compiler.definitions.IFunctionDefinition) SignatureInformation(org.eclipse.lsp4j.SignatureInformation) IASNode(org.apache.flex.compiler.tree.as.IASNode) IParameterDefinition(org.apache.flex.compiler.definitions.IParameterDefinition) IEventDefinition(org.apache.flex.compiler.definitions.IEventDefinition) IExpressionNode(org.apache.flex.compiler.tree.as.IExpressionNode) IMXMLTagAttributeData(org.apache.flex.compiler.mxml.IMXMLTagAttributeData)

Example 13 with IDefinition

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

the class ActionScriptTextDocumentService method renameDefinition.

private WorkspaceEdit renameDefinition(IDefinition definition, String newName) {
    if (definition == null) {
        if (languageClient != null) {
            MessageParams message = new MessageParams();
            message.setType(MessageType.Info);
            message.setMessage("You cannot rename this element.");
            languageClient.showMessage(message);
        }
        return new WorkspaceEdit(new HashMap<>());
    }
    WorkspaceEdit result = new WorkspaceEdit();
    Map<String, List<TextEdit>> changes = new HashMap<>();
    result.setChanges(changes);
    if (definition.getContainingFilePath().endsWith(SWC_EXTENSION)) {
        if (languageClient != null) {
            MessageParams message = new MessageParams();
            message.setType(MessageType.Info);
            message.setMessage("You cannot rename an element defined in a SWC file.");
            languageClient.showMessage(message);
        }
        return result;
    }
    if (definition instanceof IPackageDefinition) {
        if (languageClient != null) {
            MessageParams message = new MessageParams();
            message.setType(MessageType.Info);
            message.setMessage("You cannot rename a package.");
            languageClient.showMessage(message);
        }
        return result;
    }
    IDefinition parentDefinition = definition.getParent();
    if (parentDefinition != null && parentDefinition instanceof IPackageDefinition) {
        if (languageClient != null) {
            MessageParams message = new MessageParams();
            message.setType(MessageType.Info);
            message.setMessage("You cannot rename this element.");
            languageClient.showMessage(message);
        }
        return result;
    }
    for (ICompilationUnit compilationUnit : compilationUnits) {
        if (compilationUnit == null || compilationUnit instanceof SWCCompilationUnit) {
            continue;
        }
        ArrayList<TextEdit> textEdits = new ArrayList<>();
        if (compilationUnit.getAbsoluteFilename().endsWith(MXML_EXTENSION)) {
            IMXMLDataManager mxmlDataManager = currentWorkspace.getMXMLDataManager();
            MXMLData mxmlData = (MXMLData) mxmlDataManager.get(fileSpecGetter.getFileSpecification(compilationUnit.getAbsoluteFilename()));
            IMXMLTagData rootTag = mxmlData.getRootTag();
            if (rootTag != null) {
                ArrayList<ISourceLocation> units = new ArrayList<>();
                findMXMLUnits(mxmlData.getRootTag(), definition, units);
                for (ISourceLocation otherUnit : units) {
                    TextEdit textEdit = new TextEdit();
                    textEdit.setNewText(newName);
                    Range range = LanguageServerUtils.getRangeFromSourceLocation(otherUnit);
                    if (range == null) {
                        continue;
                    }
                    textEdit.setRange(range);
                    textEdits.add(textEdit);
                }
            }
        }
        IASNode ast = null;
        try {
            ast = compilationUnit.getSyntaxTreeRequest().get().getAST();
        } catch (Exception e) {
        //safe to ignore
        }
        if (ast != null) {
            ArrayList<IIdentifierNode> identifiers = new ArrayList<>();
            findIdentifiers(ast, definition, identifiers);
            for (IIdentifierNode identifierNode : identifiers) {
                TextEdit textEdit = new TextEdit();
                textEdit.setNewText(newName);
                Range range = LanguageServerUtils.getRangeFromSourceLocation(identifierNode);
                if (range == null) {
                    continue;
                }
                textEdit.setRange(range);
                textEdits.add(textEdit);
            }
        }
        if (textEdits.size() == 0) {
            continue;
        }
        URI uri = Paths.get(compilationUnit.getAbsoluteFilename()).toUri();
        changes.put(uri.toString(), textEdits);
    }
    return result;
}
Also used : HashMap(java.util.HashMap) IPackageDefinition(org.apache.flex.compiler.definitions.IPackageDefinition) MXMLData(org.apache.flex.compiler.internal.mxml.MXMLData) ArrayList(java.util.ArrayList) URI(java.net.URI) SWCCompilationUnit(org.apache.flex.compiler.internal.units.SWCCompilationUnit) IASNode(org.apache.flex.compiler.tree.as.IASNode) ArrayList(java.util.ArrayList) List(java.util.List) CompletionList(org.eclipse.lsp4j.CompletionList) ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) MessageParams(org.eclipse.lsp4j.MessageParams) IIdentifierNode(org.apache.flex.compiler.tree.as.IIdentifierNode) WorkspaceEdit(org.eclipse.lsp4j.WorkspaceEdit) Range(org.eclipse.lsp4j.Range) IMXMLTagData(org.apache.flex.compiler.mxml.IMXMLTagData) IDefinition(org.apache.flex.compiler.definitions.IDefinition) ConcurrentModificationException(java.util.ConcurrentModificationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) IMXMLDataManager(org.apache.flex.compiler.mxml.IMXMLDataManager) TextEdit(org.eclipse.lsp4j.TextEdit) ISourceLocation(org.apache.flex.compiler.common.ISourceLocation)

Example 14 with IDefinition

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

the class ActionScriptTextDocumentService method autoCompleteMemberAccess.

private void autoCompleteMemberAccess(IMemberAccessExpressionNode node, CompletionList result) {
    ASScope scope = (ASScope) node.getContainingScope().getScope();
    IExpressionNode leftOperand = node.getLeftOperandNode();
    IDefinition leftDefinition = leftOperand.resolve(currentProject);
    if (leftDefinition != null && leftDefinition instanceof ITypeDefinition) {
        ITypeDefinition typeDefinition = (ITypeDefinition) leftDefinition;
        TypeScope typeScope = (TypeScope) typeDefinition.getContainedScope();
        addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, true, result);
        return;
    }
    ITypeDefinition leftType = leftOperand.resolveType(currentProject);
    if (leftType != null) {
        TypeScope typeScope = (TypeScope) leftType.getContainedScope();
        addDefinitionsInTypeScopeToAutoCompleteActionScript(typeScope, scope, false, result);
        return;
    }
    if (leftOperand instanceof IMemberAccessExpressionNode) {
        IMemberAccessExpressionNode memberAccess = (IMemberAccessExpressionNode) leftOperand;
        String packageName = memberAccessToPackageName(memberAccess);
        if (packageName != null) {
            autoCompleteDefinitions(result, false, false, packageName, null);
            return;
        }
    }
}
Also used : IASScope(org.apache.flex.compiler.scopes.IASScope) ASScope(org.apache.flex.compiler.internal.scopes.ASScope) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) TypeScope(org.apache.flex.compiler.internal.scopes.TypeScope) IExpressionNode(org.apache.flex.compiler.tree.as.IExpressionNode) IDefinition(org.apache.flex.compiler.definitions.IDefinition) IMemberAccessExpressionNode(org.apache.flex.compiler.tree.as.IMemberAccessExpressionNode)

Example 15 with IDefinition

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

the class ActionScriptTextDocumentService method autoCompleteTypesForMXMLFromExistingTag.

/**
     * Using an existing tag, that may already have a prefix or short name,
     * populate the completion list.
     */
private void autoCompleteTypesForMXMLFromExistingTag(CompletionList result, IMXMLTagData offsetTag) {
    IMXMLDataManager mxmlDataManager = currentWorkspace.getMXMLDataManager();
    MXMLData mxmlData = (MXMLData) mxmlDataManager.get(fileSpecGetter.getFileSpecification(currentUnit.getAbsoluteFilename()));
    String tagStartShortName = offsetTag.getShortName();
    String tagPrefix = offsetTag.getPrefix();
    PrefixMap prefixMap = mxmlData.getRootTagPrefixMap();
    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)) {
                continue;
            }
            ITypeDefinition typeDefinition = (ITypeDefinition) definition;
            //or that the definition's base name matches the short name 
            if (tagStartShortName.length() == 0 || typeDefinition.getBaseName().startsWith(tagStartShortName)) {
                //in a namespace with that prefix
                if (tagPrefix.length() > 0) {
                    Collection<XMLName> tagNames = currentProject.getTagNamesForClass(typeDefinition.getQualifiedName());
                    for (XMLName tagName : tagNames) {
                        String tagNamespace = tagName.getXMLNamespace();
                        //not what we're using in this file
                        if (tagNamespace.equals(IMXMLLanguageConstants.NAMESPACE_MXML_2006)) {
                            //use the language namespace of the root tag instead
                            tagNamespace = mxmlData.getRootTag().getMXMLDialect().getLanguageNamespace();
                        }
                        String[] prefixes = prefixMap.getPrefixesForNamespace(tagNamespace);
                        for (String otherPrefix : prefixes) {
                            if (tagPrefix.equals(otherPrefix)) {
                                addDefinitionAutoCompleteMXML(typeDefinition, null, null, result);
                            }
                        }
                    }
                } else {
                    //no prefix yet, so complete the definition with a prefix
                    MXMLNamespace ns = getMXMLNamespaceForTypeDefinition(typeDefinition, mxmlData);
                    addDefinitionAutoCompleteMXML(typeDefinition, ns.prefix, ns.uri, result);
                }
            }
        }
    }
}
Also used : PrefixMap(org.apache.flex.compiler.common.PrefixMap) ICompilationUnit(org.apache.flex.compiler.units.ICompilationUnit) ITypeDefinition(org.apache.flex.compiler.definitions.ITypeDefinition) MXMLData(org.apache.flex.compiler.internal.mxml.MXMLData) IDefinition(org.apache.flex.compiler.definitions.IDefinition) ConcurrentModificationException(java.util.ConcurrentModificationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) IMXMLDataManager(org.apache.flex.compiler.mxml.IMXMLDataManager) XMLName(org.apache.flex.compiler.common.XMLName)

Aggregations

IDefinition (org.apache.flex.compiler.definitions.IDefinition)30 ArrayList (java.util.ArrayList)12 IClassDefinition (org.apache.flex.compiler.definitions.IClassDefinition)12 ITypeDefinition (org.apache.flex.compiler.definitions.ITypeDefinition)10 IASScope (org.apache.flex.compiler.scopes.IASScope)7 IIdentifierNode (org.apache.flex.compiler.tree.as.IIdentifierNode)7 FileNotFoundException (java.io.FileNotFoundException)6 IOException (java.io.IOException)6 ConcurrentModificationException (java.util.ConcurrentModificationException)6 IFunctionDefinition (org.apache.flex.compiler.definitions.IFunctionDefinition)6 IMXMLTagAttributeData (org.apache.flex.compiler.mxml.IMXMLTagAttributeData)6 ICompilationUnit (org.apache.flex.compiler.units.ICompilationUnit)6 ISourceLocation (org.apache.flex.compiler.common.ISourceLocation)5 IVariableDefinition (org.apache.flex.compiler.definitions.IVariableDefinition)5 IMXMLTagData (org.apache.flex.compiler.mxml.IMXMLTagData)5 CompletionItem (org.eclipse.lsp4j.CompletionItem)5 IEventDefinition (org.apache.flex.compiler.definitions.IEventDefinition)4 IMetaTag (org.apache.flex.compiler.definitions.metadata.IMetaTag)4 IASNode (org.apache.flex.compiler.tree.as.IASNode)4 IExpressionNode (org.apache.flex.compiler.tree.as.IExpressionNode)4