Giter Club home page Giter Club logo

Comments (5)

ivanwonder avatar ivanwonder commented on April 30, 2024 1

OK, I'll take a look.

from angular.

atscott avatar atscott commented on April 30, 2024

This appears to have been broken by angular/vscode-ng-language-service@bd6282e. @ivanwonder If you have and time, would you be able to take a look at this? I clearly don't understand the tokenizer and can't look into it more anytime soon.

from angular.

atscott avatar atscott commented on April 30, 2024

@ivanwonder Thank you! We don't necessarily need the whole implementation that TypeScript has for this because we don't care about tokenizing all the parts correctly. All we really need to know is where the start and end is of the string. But maybe the easiest way to do that is just tokenizing the whole thing correctly by copying the TS code.

from angular.

ivanwonder avatar ivanwonder commented on April 30, 2024

Yes, the tokenizer is complex, and I also can't fully understand it, and make sure this will work for us.

  1. const a =`abc`

The token is ts.SyntaxKind.NoSubstitutionTemplateLiteral which includes the CloseBraceToken. We don't need to call the reScanTemplateToken.

  1. const a = `ab${1}c`

We need to call the reScanTemplateToken when encountering a CloseBraceToken.

  1. const a = `ab${b({})}c`

This includes an object {}, we need to record the OpenBraceToken, close them all, then call the reScanTemplateToken.


But maybe the easiest way to do that is just tokenizing the whole thing correctly by copying the TS code.

I think this is what the ts.createSourceFile does. Scan the code and create the AST tree.
https://github.com/microsoft/TypeScript/blob/806d7340472082e5ff6d844ecdb70a4b5165e8c5/src/compiler/parser.ts#L1592


I have an idea about the original problem, I guess which is the diagnostics can be quite expensive. In the typescript the type checker can be interrupted.

    // Cancellation that controls whether or not we can cancel in the middle of type checking.
    // In general cancelling is *not* safe for the type checker.  We might be in the middle of
    // computing something, and we will leave our internals in an inconsistent state.  Callers
    // who set the cancellation token should catch if a cancellation exception occurs, and
    // should throw away and create a new TypeChecker.
    //
    // Currently we only support setting the cancellation token when getting diagnostics.  This
    // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
    // they no longer need the information (for example, if the user started editing again).
    var cancellationToken: CancellationToken | undefined;
function runWithCancellationToken<T>(func: () => T): T {
        try {
            return func();
        }
        catch (e) {
            if (e instanceof OperationCanceledException) {
                // We were canceled while performing the operation.  Because our type checker
                // might be a bad state, we need to throw it away.
                typeChecker = undefined!;
            }

            throw e;
        }
    }

This copy is from here. https://github.com/microsoft/TypeScript/blob/806d7340472082e5ff6d844ecdb70a4b5165e8c5/src/compiler/checker.ts#L1435
https://github.com/microsoft/TypeScript/blob/806d7340472082e5ff6d844ecdb70a4b5165e8c5/src/compiler/program.ts#L2853

Maybe we can evaluate this option, and try to throw an error in the template type checker and catch the error in the NgCompiler when the request is canceled.

from angular.

atscott avatar atscott commented on April 30, 2024

I think this is what the ts.createSourceFile does. Scan the code and create the AST tree.

Yea, this is probably the direction we should go at this point (creating a temporary source file). We can copy the same code used on the server side here:

function isInAngularContext(program: ts.Program, fileName: string, position: number) {
if (!isTypeScriptFile(fileName)) {
return true;
}
const node = findTightestNodeAtPosition(program, fileName, position);
if (node === undefined) {
return false;
}
const assignment = getPropertyAssignmentFromValue(node, 'template') ??
getPropertyAssignmentFromValue(node, 'templateUrl') ??
// `node.parent` is used because the string is a child of an array element and we want to get
// the property name
getPropertyAssignmentFromValue(node.parent, 'styleUrls') ??
getPropertyAssignmentFromValue(node, 'styleUrl');
return assignment !== null && getClassDeclFromDecoratorProp(assignment) !== null;
}

from angular.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.