| Index: editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/html/HtmlAnalyzeHelper.java
|
| diff --git a/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/html/HtmlAnalyzeHelper.java b/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/html/HtmlAnalyzeHelper.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..47f4ffc707329b23f57b1cc91f96571992143962
|
| --- /dev/null
|
| +++ b/editor/tools/plugins/com.google.dart.tools.core/src/com/google/dart/tools/core/html/HtmlAnalyzeHelper.java
|
| @@ -0,0 +1,108 @@
|
| +/*
|
| + * Copyright 2012 Dart project authors.
|
| + *
|
| + * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
|
| + * in compliance with the License. You may obtain a copy of the License at
|
| + *
|
| + * http://www.eclipse.org/legal/epl-v10.html
|
| + *
|
| + * Unless required by applicable law or agreed to in writing, software distributed under the License
|
| + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
| + * or implied. See the License for the specific language governing permissions and limitations under
|
| + * the License.
|
| + */
|
| +
|
| +package com.google.dart.tools.core.html;
|
| +
|
| +import com.google.common.base.CharMatcher;
|
| +import com.google.common.base.Charsets;
|
| +import com.google.common.collect.Maps;
|
| +import com.google.common.io.Files;
|
| +import com.google.dart.tools.core.DartCore;
|
| +import com.google.dart.tools.core.analysis.AnalysisServer;
|
| +import com.google.dart.tools.core.internal.model.PackageLibraryManagerProvider;
|
| +
|
| +import org.eclipse.core.resources.IFile;
|
| +
|
| +import java.io.File;
|
| +import java.util.Map;
|
| +import java.util.regex.Matcher;
|
| +import java.util.regex.Pattern;
|
| +
|
| +/**
|
| + * Helper class to analyze Dart code inside of HTML files.
|
| + */
|
| +public class HtmlAnalyzeHelper {
|
| + private static final Map<File, File> dartToHtmlMap = Maps.newConcurrentMap();
|
| +
|
| + /**
|
| + * This method should be called from builder to notify that HTML file was changed and should be
|
| + * analyzed. Note that this is long operation, don't call it from UI thread.
|
| + */
|
| + public static void analyze(IFile htmlResource) {
|
| + File htmlFile = htmlResource.getLocation().toFile();
|
| + try {
|
| + analyzeEx(htmlFile);
|
| + } catch (Throwable e) {
|
| + DartCore.logError(e);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * @return the HTML {@link File} from which given Dart {@link File} was generated, may be same
|
| + * {@link File} if it was not generated from HTML.
|
| + */
|
| + public static File getSourceHtmlFile(File dartFile) {
|
| + File htmlFile = dartToHtmlMap.get(dartFile);
|
| + if (htmlFile != null) {
|
| + return htmlFile;
|
| + }
|
| + return dartFile;
|
| +
|
| + }
|
| +
|
| + /**
|
| + * Implementation of {@link #analyze(IFile)} which can throw exceptions.
|
| + */
|
| + private static void analyzeEx(File htmlFile) throws Exception {
|
| + String content = Files.toString(htmlFile, Charsets.UTF_8);
|
| + // extract <script type="application/dart"> scripts
|
| + int searchStart = 0;
|
| + Pattern pattern = Pattern.compile("\\<\\s*script\\s+type=['\"]application/dart['\"]\\s*\\>\\s*(.*)");
|
| + Matcher matcher = pattern.matcher(content);
|
| + while (true) {
|
| + // find next script
|
| + if (!matcher.find(searchStart)) {
|
| + break;
|
| + }
|
| + // prepare script start/end
|
| + int scriptStart = matcher.start(1);
|
| + int scriptEnd = content.indexOf("</script>", scriptStart);
|
| + if (scriptEnd == -1) {
|
| + break;
|
| + }
|
| + searchStart = scriptEnd;
|
| + // extract script
|
| + String script = content.substring(scriptStart, scriptEnd);
|
| + // prepare prefix to place script at the same line/offset as it was in HTML
|
| + String scriptPrefix;
|
| + {
|
| + String contentPrefix = content.substring(0, scriptStart);
|
| + scriptPrefix = CharMatcher.anyOf("\r\n").negate().replaceFrom(contentPrefix, ' ');
|
| + }
|
| + // create temporary File with Dart code
|
| + File scriptFile = File.createTempFile("dartInHtml", ".dart");
|
| + Files.write(scriptPrefix + script, scriptFile, Charsets.UTF_8);
|
| + dartToHtmlMap.put(scriptFile, htmlFile);
|
| + // ask AnalysisServer to analyze Dart file
|
| + {
|
| + AnalysisServer server = PackageLibraryManagerProvider.getDefaultAnalysisServer();
|
| + server.getSavedContext().resolve(scriptFile, 30 * 1000);
|
| + // clean up
|
| + scriptFile.delete();
|
| + // in theory, we should remove mapping, but practically it may be requested later
|
| +// dartToHtmlMap.remove(scriptFile);
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|