blob: dd8e07d2139dc99f415441896c014913e2bfe59a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Christian Pontesegger and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Christian Pontesegger - initial API and implementation
*******************************************************************************/package org.eclipse.ease.lang.javascript.ui;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.ease.modules.ModuleDefinition;
import org.eclipse.ease.modules.ModuleHelper;
import org.eclipse.ease.service.IScriptService;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.jsdt.ui.text.java.ContentAssistInvocationContext;
public class ModuleProposalCalculator {
private static final Pattern LOAD_MODULE_PATTERN = Pattern.compile("loadModule\\([\"'](.*)[\"']\\)");
private static final Pattern LINE_DATA_PATTERN = Pattern.compile(".*?([^\\p{Alnum}]?)(\\p{Alnum}*)$");
final IScriptService scriptService = (IScriptService) PlatformUI.getWorkbench().getService(IScriptService.class);
/**
* Get a collection of module definitions for loadModule commands in code. Parses the source code before the current cursor position for <i>loadModule</i>
* commands. Afterwards extracts module definitions for detected modules. Currently does not follow include files.
*
* @param context
* content assist context
* @return collection of module definitions relevant for context assist
*/
protected Collection<ModuleDefinition> getLoadedModules(final ContentAssistInvocationContext context) {
Collection<ModuleDefinition> modules = new HashSet<ModuleDefinition>();
// environment module is always present
modules.add(scriptService.getAvailableModules().get("/System/Environment"));
try {
// extract text before cursor
IDocument document = context.getDocument();
String prefix = document.get(0, context.getInvocationOffset());
for (String name : getModuleNames(prefix)) {
String fullName = ModuleHelper.resolveName(name);
ModuleDefinition definition = scriptService.getAvailableModules().get(fullName);
if (definition != null)
modules.add(definition);
}
} catch (BadLocationException e1) {
e1.printStackTrace();
// ignore
}
return modules;
}
/**
* Extract names of loaded modules within provided code. Will only detect string literals, so if the loadModule parameter is not a single string, extraction
* will fail.
*
* @param code
* code to parse
* @return collection of module names
*/
private Collection<String> getModuleNames(final String code) {
Collection<String> modules = new HashSet<String>();
Matcher matcher = LOAD_MODULE_PATTERN.matcher(code);
while (matcher.find())
modules.add(matcher.group(1));
return modules;
}
/**
* Extract context relevant information from current line. The returned matcher locates the last alphanumeric word in the line and an optional non
* alphanumeric character right before that word. result.group(1) contains the last non-alphanumeric token (eg a dot, brackets, arithmetic operators, ...),
* result.group(2) contains the alphanumeric text. This text can be used to filter content assist proposals.
*
* @param context
* content assist context
* @return matcher containing content assist information
* @throws BadLocationException
*/
protected Matcher matchLastToken(final ContentAssistInvocationContext context) throws BadLocationException {
String data = getCurrentLine(context);
return LINE_DATA_PATTERN.matcher(data);
}
/**
* Extract text from current line up to the cursor position
*
* @param context
* content assist context
* @return current line data
* @throws BadLocationException
*/
protected String getCurrentLine(final ContentAssistInvocationContext context) throws BadLocationException {
IDocument document = context.getDocument();
int lineNumber = document.getLineOfOffset(context.getInvocationOffset());
IRegion lineInformation = document.getLineInformation(lineNumber);
return document.get(lineInformation.getOffset(), context.getInvocationOffset() - lineInformation.getOffset());
}
}