@Override public Map<URI, Set<SymbolInformation>> getFileSymbols() { return indexer.getFileSymbols(); }
@Override public Optional<Location> gotoDefinition(URI uri, Position position) { List<Location> possibleLocations = indexer.getGotoReferenced().keySet().stream() .filter(loc -> uri.equals(URI.create(loc.getUri())) && Ranges.contains(loc.getRange(), position)) // If there is more than one result, we want the symbol whose range starts the latest, with a secondary // sort of earliest end range. .sorted((l1, l2) -> Ranges.POSITION_COMPARATOR.compare(l1.getRange().getEnd(), l2.getRange().getEnd())) .sorted((l1, l2) -> Ranges.POSITION_COMPARATOR.reversed().compare(l1.getRange().getStart(), l2.getRange().getStart())) .collect(Collectors.toList()); if (possibleLocations.isEmpty()) { return Optional.absent(); } return indexer.gotoReferenced(possibleLocations.get(0)); }
@Override public Map<Location, Set<Location>> getReferences() { return indexer.getReferences(); }
@Override public Set<Location> findReferences(ReferenceParams params) { URI paramsUri = Uris.resolveToRoot(workspaceRoot, params.getTextDocument().getUri()); Set<SymbolInformation> symbols = indexer.getFileSymbols().get(paramsUri); if (symbols == null) { return ImmutableSet.of(); indexer.getGotoReferenced().keySet().stream() .filter(loc -> paramsUri.toString().equals(loc.getUri()) && Ranges.isValid(loc.getRange()) && Ranges.contains(loc.getRange(), params.getPosition()) && indexer.gotoReferenced(loc).isPresent()) .map(loc -> new ReferenceLocation(loc, true)) .collect(Collectors.toSet()); Location referredLocation = foundReferencedLocation.getLocation(); if (foundReferencedLocation.getIsReferencedLocation()) { referredLocation = indexer.gotoReferenced(foundReferencedLocation.getLocation()).get(); foundReferences = indexer.findReferences(referredLocation).or(Sets.newHashSet()); } else { foundReferences = indexer.findReferences(foundReferencedLocation.getLocation()).or(Sets.newHashSet());
@Override public void parseAllSymbols() { Indexer newIndexer = new Indexer(); CompilationUnit unit = unitSupplier.get(); GroovyLocations.createClassDefinitionLocation(sourceUri, clazz), Optional.fromNullable(clazz.getOuterClass()).transform(ClassNode::getName)); newIndexer.addSymbol(sourceUri, classSymbol); .filter(node -> !node.getName().equals(GROOVY_DEFAULT_INTERFACE) && classes.containsKey(node.getName())) .forEach(node -> newIndexer.addReference(classes.get(node.getName()), GroovyLocations.createLocation(sourceUri, node))); && !clazz.getSuperClass().getName().equals(GroovyConstants.JAVA_DEFAULT_OBJECT) && classes.containsKey(clazz.getSuperClass().getName())) { newIndexer.addReference(classes.get(clazz.getSuperClass().getName()), classSymbol.getLocation()); newIndexer.addSymbol(sourceUri, symbol); if (classes.containsKey(field.getType().getName())) { newIndexer.addReference(classes.get(field.getType().getName()), GroovyLocations.createLocation(sourceUri, field.getType())); classFields.put(field.getName(), field); SymbolInformation symbol = getVariableSymbolInformation(scriptClass.getName(), sourceUri, variable); newIndexer.addSymbol(sourceUnit.getSource().getURI(), symbol); if (classes.containsKey(variable.getType().getName())) { newIndexer.addReference(classes.get(variable.getType().getName()),
@Override public void visitDeclarationExpression(DeclarationExpression expression) { if (expression.getLeftExpression() instanceof Variable) { Variable var = (Variable) expression.getLeftExpression(); SymbolInformation symbol = getVariableSymbolInformation(var); indexer.addSymbol(uri, symbol); if (var.getType() != null && classes.containsKey(var.getType().getName())) { indexer.addReference(classes.get(var.getType().getName()), createLocation(var.getType())); } } super.visitDeclarationExpression(expression); }
@Override public void visitClassExpression(ClassExpression expression) { // Add reference to class if (expression.getType() != null && classes.containsKey(expression.getType().getName())) { indexer.addReference(classes.get(expression.getType().getName()), createLocation(expression)); } super.visitClassExpression(expression); }
private void parseMethod(Indexer newIndexer, URI sourceUri, ClassNode parent, Map<String, Location> classes, Map<String, FieldNode> classFields, MethodNode method) { SymbolInformation methodSymbol = createSymbolInformation(method.getName(), SymbolKind.Method, GroovyLocations.createLocation(sourceUri, method), Optional.of(parent.getName())); newIndexer.addSymbol(sourceUri, methodSymbol); // Method parameters method.getVariableScope().getDeclaredVariables().values().forEach(variable -> { SymbolInformation variableSymbol = getVariableSymbolInformation(method.getName(), sourceUri, variable); newIndexer.addSymbol(sourceUri, variableSymbol); if (classes.containsKey(variable.getType().getName())) { newIndexer.addReference(classes.get(variable.getType().getName()), GroovyLocations.createLocation(sourceUri, variable.getType())); } }); // Return type if (classes.containsKey(method.getReturnType().getName())) { newIndexer.addReference(classes.get(method.getReturnType().getName()), GroovyLocations.createLocation(sourceUri, method.getReturnType())); } // We only want to visit the method if its not generated if (Ranges.isValid(methodSymbol.getLocation().getRange())) { // Visit the method if (method.getCode() instanceof BlockStatement) { BlockStatement blockStatement = (BlockStatement) method.getCode(); blockStatement.visit(new MethodVisitor(newIndexer, sourceUri, parent, classes, classFields, Optional.of(method), workspaceUriSupplier)); } } }
@Override public void visitStaticMethodCallExpression(StaticMethodCallExpression expression) { List<MethodNode> possibleMethods = expression.getOwnerType().getMethods(expression.getMethodAsString()); if (!possibleMethods.isEmpty() && expression.getArguments() instanceof ArgumentListExpression) { ArgumentListExpression actualArguments = (ArgumentListExpression) expression.getArguments(); possibleMethods.stream() .filter(method -> areEquals(method.getParameters(), actualArguments)) .forEach(method -> indexer.addReference(createLocation(method), createLocation(expression))); } super.visitStaticMethodCallExpression(expression); }
@Override public void visitCatchStatement(CatchStatement statement) { // Add reference to class exception if (classes.containsKey(statement.getExceptionType().getName())) { indexer.addReference(classes.get(statement.getExceptionType().getName()), createLocation(statement.getExceptionType())); } // TODO(#125): add a symbol for the exception variables. Right now statement.getVariable() returns a Parameter // with an invalid location. super.visitCatchStatement(statement); }
@Override public Set<SymbolInformation> getFilteredSymbols(String query) { checkNotNull(query, "query must not be null"); Pattern pattern = getQueryPattern(query); return indexer.getFileSymbols().values().stream().flatMap(Collection::stream) .filter(symbol -> pattern.matcher(symbol.getName()).matches()) .collect(Collectors.toSet()); }
@Override public void visitConstructorCallExpression(ConstructorCallExpression expression) { if (expression.getType() != null && classes.containsKey(expression.getType().getName())) { indexer.addReference(classes.get(expression.getType().getName()), createLocation(expression)); } super.visitConstructorCallExpression(expression); }
@Override public void visitVariableExpression(VariableExpression expression) { if (expression.getAccessedVariable() != null) { SymbolInformation symbol = getVariableSymbolInformation(expression.getAccessedVariable()); if (Ranges.isValid(symbol.getLocation().getRange())) { indexer.addReference(symbol.getLocation(), createLocation(expression)); } else if (classFields.containsKey(expression.getAccessedVariable().getName())) { Location location = createLocation(classFields.get(expression.getAccessedVariable().getName())); indexer.addReference(location, createLocation(expression)); } } super.visitVariableExpression(expression); }
@Override public void visitPropertyExpression(PropertyExpression expression) { if (expression.getObjectExpression() instanceof VariableExpression) { // This means it's a non static reference to a class variable VariableExpression var = (VariableExpression) expression.getObjectExpression(); FieldNode field = var.getType().getField(expression.getProperty().getText()); if (classes.containsKey(var.getType().getName())) { indexer.addReference(createLocation(URI.create(classes.get(var.getType().getName()).getUri()), field), createLocation(expression.getProperty())); } } else if (expression.getObjectExpression() instanceof ClassExpression) { // This means it's a static reference to a class variable ClassExpression classExpression = (ClassExpression) expression.getObjectExpression(); FieldNode field = classExpression.getType().getField(expression.getProperty().getText()); if (classes.containsKey(classExpression.getType().getName())) { indexer.addReference( createLocation(URI.create(classes.get(classExpression.getType().getName()).getUri()), field), createLocation(expression.getProperty())); } } super.visitPropertyExpression(expression); }
.filter(method -> areEquals(method.getParameters(), actualArguments)) .forEach(method -> { indexer.addReference( createLocation(URI.create(classes.get(parentClass.getName()).getUri()), method), createLocation(call));