blob: f351eac34f4db403071f16b9c83a6ee8888d9c09 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 xored software, Inc.
*
* 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:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.ui.util;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.core.IBuffer;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.corext.util.Strings;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.swt.SWT;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
public class CodeGeneration {
public static String evaluateTemplate(TemplateContext context,
Template template, String[] fullLineVariables) throws CoreException {
TemplateBuffer buffer;
try {
buffer = context.evaluate(template);
if (buffer == null)
return null;
String str = fixFullLineVariables(buffer, fullLineVariables);
if (Strings.containsOnlyWhitespaces(str)) {
return null;
}
return str;
} catch (BadLocationException e) {
throw new CoreException(Status.CANCEL_STATUS);
} catch (TemplateException e) {
throw new CoreException(Status.CANCEL_STATUS);
}
}
// remove lines for empty variables, prefix multi-line variables
private static String fixFullLineVariables(TemplateBuffer buffer,
String[] variables) throws MalformedTreeException,
BadLocationException {
IDocument doc = new Document(buffer.getString());
int nLines = doc.getNumberOfLines();
MultiTextEdit edit = new MultiTextEdit();
Set<Integer> removedLines = new HashSet<Integer>();
for (int i = 0; i < variables.length; i++) {
TemplateVariable position = findVariable(buffer, variables[i]);
if (position == null) {
continue;
}
if (position.getLength() > 0) {
int[] offsets = position.getOffsets();
for (int j = 0; j < offsets.length; j++) {
final int offset = offsets[j];
try {
int startLine = doc.getLineOfOffset(offset);
int startOffset = doc.getLineOffset(startLine);
int endLine = doc.getLineOfOffset(offset
+ position.getLength());
String prefix = doc.get(startOffset, offset
- startOffset);
if (prefix.length() > 0 && startLine < endLine) {
for (int line = startLine + 1; line <= endLine; ++line) {
int lineOffset = doc.getLineOffset(line);
edit.addChild(new InsertEdit(lineOffset, prefix));
}
}
} catch (BadLocationException exc) {
break;
}
}
} else {
int[] offsets = position.getOffsets();
for (int k = 0; k < offsets.length; k++) {
int line = doc.getLineOfOffset(offsets[k]);
IRegion lineInfo = doc.getLineInformation(line);
int offset = lineInfo.getOffset();
String str = doc.get(offset, lineInfo.getLength());
if (Strings.containsOnlyWhitespaces(str)
&& nLines > line + 1 && removedLines.add(line)) {
int nextStart = doc.getLineOffset(line + 1);
int length = nextStart - offset;
edit.addChild(new DeleteEdit(offset, length));
}
}
}
}
edit.apply(doc, 0);
return doc.get();
}
private static TemplateVariable findVariable(TemplateBuffer buffer,
String variable) {
TemplateVariable[] positions = buffer.getVariables();
for (int i = 0; i < positions.length; i++) {
TemplateVariable curr = positions[i];
if (variable.equals(curr.getType())) {
return curr;
}
}
return null;
}
/**
* Examines a string and returns the first line delimiter found.
*/
public static String getLineDelimiterUsed(IModelElement elem)
throws ModelException {
if (elem == null)
return Util.EMPTY_STRING;
ISourceModule cu = (ISourceModule) elem
.getAncestor(IModelElement.SOURCE_MODULE);
if (cu != null && cu.exists()) {
IBuffer buf = cu.getBuffer();
int length = buf.getLength();
for (int i = 0; i < length; i++) {
char ch = buf.getChar(i);
if (ch == SWT.CR) {
if (i + 1 < length) {
if (buf.getChar(i + 1) == SWT.LF) {
return "\r\n"; //$NON-NLS-1$
}
}
return "\r"; //$NON-NLS-1$
} else if (ch == SWT.LF) {
return "\n"; //$NON-NLS-1$
}
}
}
return getProjectLineDelimiter(elem.getScriptProject());
}
private static String getProjectLineDelimiter(IScriptProject cProject) {
IProject project = null;
if (cProject != null)
project = cProject.getProject();
String lineDelimiter = getLineDelimiterPreference(project);
if (lineDelimiter != null)
return lineDelimiter;
return Util.LINE_SEPARATOR;
}
public static String getLineDelimiterPreference(IProject project) {
IScopeContext[] scopeContext;
if (project != null) {
// project preference
scopeContext = new IScopeContext[] { new ProjectScope(project) };
String lineDelimiter = Platform.getPreferencesService().getString(
Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null,
scopeContext);
if (lineDelimiter != null)
return lineDelimiter;
}
// workspace preference
scopeContext = new IScopeContext[] { InstanceScope.INSTANCE };
String platformDefault = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
return Platform.getPreferencesService().getString(Platform.PI_RUNTIME,
Platform.PREF_LINE_SEPARATOR, platformDefault, scopeContext);
}
}